说在前面
前期回顾
sharding-jdbc源码解析 更新完毕
spring源码解析 更新完毕
spring-mvc源码解析 更新完毕
spring-tx源码解析 更新完毕
spring-boot源码解析 更新完毕
rocketmq源码解析 更新完毕
dubbbo源码解析 更新完毕
netty源码解析 更新完毕
spring源码架构更新完毕
spring-mvc源码架构更新完毕
springboot源码架构更新中
github https://github.com/tianheframe
sharding-jdbc源码解析 更新完毕
rocketmq源码解析 更新完毕
seata 源码解析 更新完毕
dubbo 源码解析 更新完毕
netty 源码解析 更新完毕
源码解析

org.springframework.boot.Banner banner接口类
void printBanner(Environment environment, Class> sourceClass, PrintStream out);
打印banner
enum Mode { /** * Disable printing of the banner. */ OFF, /** * Print the banner to System.out. */ CONSOLE, /** * Print the banner to the log file. */ LOG }
打印banner的三种方式,off禁止,console控制台,log 文件
org.springframework.boot.ResourceBanner 基于txt文件的banner打印
org.springframework.boot.SpringBootBanner 打印spring的banner
org.springframework.boot.ImageBanner 打印image的banner
org.springframework.boot.ApplicationArguments 提供对用于运行spring应用程序的参数的访问。
String[] getSourceArgs();
返回传递给应用程序的原始未处理参数。
Set<String> getOptionNames();
返回所有选项参数的名称。例如,如果参数是“——foo=bar——debug”,那么将返回值["foo", "debug"]。
boolean containsOption(String name);
返回从参数中解析的选项参数集是否包含具有给定名称的选项。
List<String> getOptionValues(String name);
返回与具有给定名称的arguments选项关联的值集合。如果该选项存在且没有参数(例如:"——foo"),则返回一个空集合([]),如果该选项存在并且只有一个值(例如。"——foo=bar"),返回一个只有一个元素的集合(["bar"]),如果该选项存在并具有多个值(例如,返回一个集合,其中每个值都有对应的元素(["bar", "baz"]),如果不存在该选项,则返回null
org.springframework.boot.DefaultApplicationArguments ApplicationArguments的默认实现
org.springframework.boot.context.properties.ConfigurationBeanFactoryMetaData 在bean工厂初始化期间记忆@Bean定义元数据的实用程序类。
实现了org.springframework.beans.factory.config.BeanFactoryPostProcessor接口
private ConfigurableListableBeanFactory beanFactory;
beanFactory
@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory;// 加载BeanFactory的BeanDefinition元数据 for (String name : beanFactory.getBeanDefinitionNames()) { BeanDefinition definition = beanFactory.getBeanDefinition(name); String method = definition.getFactoryMethodName(); String bean = definition.getFactoryBeanName(); if (method != null && bean != null) { this.beans.put(name, new MetaData(bean, method)); } } }
重写了org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory方法。
org.springframework.boot.SpringApplicationBannerPrinter 用SpringApplication打印 application bananer
org.springframework.boot.bind.YamlConfigurationFactory 通过将某些YAML绑定到指定类型的对象,然后选择在其上运行验证器来验证某些YAML。
private Validator validator;
validator
@Override @SuppressWarnings("unchecked") public void afterPropertiesSet() throws Exception { if (this.yaml == null) { Assert.state(this.resource != null, "Resource should not be null"); this.yaml = StreamUtils.copyToString(this.resource.getInputStream(), Charset.defaultCharset()); } Assert.state(this.yaml != null, "Yaml document should not be null: " + "either set it directly or set the resource to load it from"); try { if (logger.isTraceEnabled()) { logger.trace(String.format("Yaml document is %n%s", this.yaml)); } Constructor constructor = new YamlJavaBeanPropertyConstructor(this.type, this.propertyAliases);// 加载yaml配置文件 this.configuration = (T) (new Yaml(constructor)).load(this.yaml); if (this.validator != null) {// 对配置文件进行验证 validate(); } } catch (YAMLException ex) { if (this.exceptionIfInvalid) { throw ex; } logger.error("Failed to load YAML validation bean. " + "Your YAML file may be invalid.", ex); } }
重写了org.springframework.beans.factory.InitializingBean#afterPropertiesSet方法,加载yaml配置文件在对配置文件进行验证
org.springframework.boot.bind.YamlConfigurationFactory#validate
private void validate() throws BindException { BindingResult errors = new BeanPropertyBindingResult(this.configuration, "configuration");// 调用验证器对配置文件进行验证 this.validator.validate(this.configuration, errors); if (errors.hasErrors()) {// 对验证的错误进行处理 logger.error("YAML configuration failed validation"); for (ObjectError error : errors.getAllErrors()) { logger.error(getErrorMessage(error)); } if (this.exceptionIfInvalid) { BindException summary = new BindException(errors); throw summary; } } }
@Override public Class> getObjectType() { if (this.configuration == null) { return Object.class; } return this.configuration.getClass(); }
重写factoryBean的方法,返回配置类的类型
@Override public boolean isSingleton() { return true; }
返回配置类是否是单例的,这里是单例的
@Override public T getObject() throws Exception { if (this.configuration == null) { afterPropertiesSet(); } return this.configuration; }
返回配置类,如果配置类为空就重新加载配置文件
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Configurationpublic @interface SpringBootConfiguration {}
指示类提供Spring引导应用程序@Configuration。可以作为Spring的标准@Configuration注释的替代,以便自动找到配置(例如在测试中)。应用程序应该只包含一个@SpringBootConfiguration,大多数惯用的Spring引导应用程序将从@SpringBootApplication继承它。
org.springframework.boot.builder.SpringApplicationBuilder SpringApplication配置构造器
applicationprivate final SpringApplication application;
application
private ConfigurableApplicationContext context;
context
private final AtomicBoolean running = new AtomicBoolean(false);
springApplication应用程序是否运行
public SpringApplicationBuilder(Object... sources) { this.application = createSpringApplication(sources); }
创建SpringApplication,org.springframework.boot.builder.SpringApplicationBuilder#createSpringApplication 从给定的源创建一个新的SpringApplication实例。子类可以覆盖,以便提供SpringApplication的自定义子类
protected SpringApplication createSpringApplication(Object... sources) { return new SpringApplication(sources); }
org.springframework.boot.SpringApplication#SpringApplication(java.lang.Object...) 创建一个新的SpringApplication实例。应用程序上下文将从指定的源加载bean。可以在调用run(String…)之前定制实例。
public SpringApplication(Object... sources) { initialize(sources); }
org.springframework.boot.SpringApplication#initialize 初始化
private void initialize(Object[] sources) { if (sources != null && sources.length > 0) { this.sources.addAll(Arrays.asList(sources)); } this.webEnvironment = deduceWebEnvironment();// 加载初始化器 -》 setInitializers((Collection) getSpringFactoriesInstances( ApplicationContextInitializer.class));// 加载监听器 setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));// 根据main方法找出程序的启动类 this.mainApplicationClass = deduceMainApplicationClass(); }
org.springframework.boot.SpringApplication#getSpringFactoriesInstances(java.lang.Class) 加载application初始化器并设置
private Collection extends T> getSpringFactoriesInstances(Class<T> type) { return getSpringFactoriesInstances(type, new Class>[] {}); }
org.springframework.boot.SpringApplication#getSpringFactoriesInstances(java.lang.Class, java.lang.Class>[], java.lang.Object...)
private Collection extends T> getSpringFactoriesInstances(Classtype, Class>[] parameterTypes, Object... args) { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // Use names and ensure unique to protect against duplicates// 加载META-INF/spring.factories配置的SpringApplicationRunListener监听器 Set<String> names = new LinkedHashSet<String>( SpringFactoriesLoader.loadFactoryNames(type, classLoader));// 创建META-INF/spring.factories配置的SpringApplicationRunListener监听器对象 List instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); AnnotationAwareOrderComparator.sort(instances); return instances; }
org.springframework.core.io.support.SpringFactoriesLoader#loadFactoryNames 加载META-INF/spring.factories这个路径下的类
public static List<String> loadFactoryNames(Class> factoryClass, ClassLoader classLoader) { String factoryClassName = factoryClass.getName(); try { Enumeration ex = classLoader != null?classLoader.getResources("META-INF/spring.factories"):ClassLoader.getSystemResources("META-INF/spring.factories"); ArrayList result = new ArrayList(); while(ex.hasMoreElements()) { URL url = (URL)ex.nextElement(); Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url)); String propertyValue = properties.getProperty(factoryClassName); String[] var8 = StringUtils.commaDelimitedListToStringArray(propertyValue); int var9 = var8.length; for(int var10 = 0; var10 < var9; ++var10) { String factoryName = var8[var10]; result.add(factoryName.trim()); } } return result; } catch (IOException var12) { throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var12); } }
org.springframework.boot.SpringApplication#createSpringFactoriesInstances 创建META-INF/spring.factories路径下的类
private List createSpringFactoriesInstances(Classtype, Class>[] parameterTypes, ClassLoader classLoader, Object[] args, Set<String> names) { List instances = new ArrayList(names.size()); for (String name : names) { try { Class> instanceClass = ClassUtils.forName(name, classLoader); Assert.isAssignable(type, instanceClass); Constructor> constructor = instanceClass .getDeclaredConstructor(parameterTypes); T instance = (T) BeanUtils.instantiateClass(constructor, args); instances.add(instance); } catch (Throwable ex) { throw new IllegalArgumentException( "Cannot instantiate " + type + " : " + name, ex); } } return instances; }
加载ApplicationContextInitializer、ApplicationListener并初始化设置,根据main方法找到SpringApplication程序启动类
private Class> deduceMainApplicationClass() { try { StackTraceElement[] stackTrace = new RuntimeException().getStackTrace(); for (StackTraceElement stackTraceElement : stackTrace) { if ("main".equals(stackTraceElement.getMethodName())) { return Class.forName(stackTraceElement.getClassName()); } } } catch (ClassNotFoundException ex) { // Swallow and continue } return null; }
public ConfigurableApplicationContext run(String... args) { if (this.running.get()) { // If already created we just return the existing context 如果已经创建,则返回现有上下文 return this.context; } configureAsChildIfNecessary(args); if (this.running.compareAndSet(false, true)) { synchronized (this.running) { // If not already running copy the sources over and then run. 如果还没有运行,复制源代码,然后运行。// 启动spring boot应用程序 this.context = build().run(args); } } return this.context; }
使用提供的命令行args创建应用程序上下文(如果指定了它的父上下文)。如果尚未启动,则先用相同的参数运行父进程。
public ConfigurableApplicationContext run(String... args) { if (this.running.get()) { // If already created we just return the existing context 如果已经创建,则返回现有上下文 return this.context; } configureAsChildIfNecessary(args); if (this.running.compareAndSet(false, true)) { synchronized (this.running) { // If not already running copy the sources over and then run. 如果还没有运行,复制源代码,然后运行。// 启动spring boot应用程序 this.context = build().run(args); } } return this.context; }
运行程序上下文,如果配置的有上一级上下文,先运行上一级上下文
public SpringApplicationBuilder initializers( ApplicationContextInitializer>... initializers) { this.application.addInitializers(initializers); return this; }
向应用程序添加一些初始化器(在加载任何bean定义之前应用于ApplicationContext)。
public SpringApplicationBuilder listeners(ApplicationListener>... listeners) { this.application.addListeners(listeners); return this; }
向应用程序添加一些侦听器(在上下文运行后侦听SpringApplication事件和常规Spring事件)。任何同时也是ApplicationContextInitializer的侦听器都将自动添加到初始化器中。
org.springframework.boot.CommandLineRunner 接口,用于指示当bean包含在spring应用程序中时它应该运行。可以在相同的应用程序上下文中定义多个CommandLineRunner bean,并且可以使用ordered接口或@Order注释进行排序。如果需要访问ApplicationArguments而不是原始字符串数组,请考虑使用ApplicationRunner。
void run(String... args) throws Exception;
运行CommandLineRunner
org.springframework.boot.ApplicationRunner 接口,用于指示当bean包含在spring应用程序中时它应该运行。可以在相同的应用程序上下文中定义多个ApplicationRunner bean,并且可以使用ordered接口或@Order注释进行排序。
void run(ApplicationArguments args) throws Exception;
运行ApplicationRunner
org.springframework.boot.SpringApplication 类,可用于从Java主方法引导和启动Spring应用程序。默认情况下,类将执行以下步骤来引导您的应用程序:
创建一个适当的ApplicationContext实例(取决于您的类路径),注册一个CommandLinePropertySource,将命令行参数公开为Spring属性,刷新应用程序上下文,加载所有单例bean,触发任何CommandLineRunner bean,spring应用程序可以从各种不同的来源读取bean。一般建议使用单一的@Configuration类来引导应用程序,但是,也可以使用以下任何资源:类——由带注释的beandefinitionreader加载的Java类,Resource—由XmlBeanDefinitionReader加载的XML资源,或者由GroovyBeanDefinitionReader加载的groovy脚本,包——一个由ClassPathBeanDefinitionScanner扫描的Java包,CharSequence——类名、资源句柄或包名。如果不能将CharSequence解析为类,也不能解析为存在的资源,那么它将被视为一个包。
public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context." + "annotation.AnnotationConfigApplicationContext";
将默认用于非web环境的应用程序上下文的类名。
public static final String DEFAULT_WEB_CONTEXT_CLASS = "org.springframework." + "boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext";
web环境默认使用的应用程序上下文的类名。
private static final String[] WEB_ENVIRONMENT_CLASSES = { "javax.servlet.Servlet", "org.springframework.web.context.ConfigurableWebApplicationContext" };
webApplicationContext
private Class> mainApplicationClass;
springboot程序的运行类
private Banner.Mode bannerMode = Banner.Mode.CONSOLE;
在控制台打印banner
private Banner banner;
banner
private Class extends ConfigurableApplicationContext> applicationContextClass;
applicationContextClass
private List>> initializers;
initializers
private List>> listeners;
listeners
public SpringApplication(Object... sources) { initialize(sources); }
创建一个新的SpringApplication实例。应用程序上下文将从指定的源加载bean。可以在调用run(String…)之前定制实例。
org.springframework.boot.SpringApplication#initialize
private void initialize(Object[] sources) { if (sources != null && sources.length > 0) { this.sources.addAll(Arrays.asList(sources)); } this.webEnvironment = deduceWebEnvironment();// 加载初始化器 -》 setInitializers((Collection) getSpringFactoriesInstances( ApplicationContextInitializer.class));// 加载监听器 setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));// 根据main方法找出程序的启动类 this.mainApplicationClass = deduceMainApplicationClass(); }
org.springframework.boot.SpringApplication#getSpringFactoriesInstances(java.lang.Class)
private Collection extends T> getSpringFactoriesInstances(Class<T> type) { return getSpringFactoriesInstances(type, new Class>[] {}); }
org.springframework.boot.SpringApplication#getSpringFactoriesInstances(java.lang.Class, java.lang.Class>[], java.lang.Object...)
private Collection extends T> getSpringFactoriesInstances(Classtype, Class>[] parameterTypes, Object... args) { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // Use names and ensure unique to protect against duplicates// 加载META-INF/spring.factories配置的SpringApplicationRunListener监听器 Set<String> names = new LinkedHashSet<String>( SpringFactoriesLoader.loadFactoryNames(type, classLoader));// 创建META-INF/spring.factories配置的SpringApplicationRunListener监听器对象 List instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); AnnotationAwareOrderComparator.sort(instances); return instances; }
org.springframework.boot.SpringApplication#createSpringFactoriesInstances
private List createSpringFactoriesInstances(Classtype, Class>[] parameterTypes, ClassLoader classLoader, Object[] args, Set<String> names) { List instances = new ArrayList(names.size()); for (String name : names) { try { Class> instanceClass = ClassUtils.forName(name, classLoader); Assert.isAssignable(type, instanceClass); Constructor> constructor = instanceClass .getDeclaredConstructor(parameterTypes); T instance = (T) BeanUtils.instantiateClass(constructor, args); instances.add(instance); } catch (Throwable ex) { throw new IllegalArgumentException( "Cannot instantiate " + type + " : " + name, ex); } } return instances; }
从META-INF/spring.factories路径加载ApplicationContextInitializer、ApplicationListener并初始化
org.springframework.boot.SpringApplication#deduceMainApplicationClass 判断有main方法的程序启动类
private Class> deduceMainApplicationClass() { try { StackTraceElement[] stackTrace = new RuntimeException().getStackTrace(); for (StackTraceElement stackTraceElement : stackTrace) { if ("main".equals(stackTraceElement.getMethodName())) { return Class.forName(stackTraceElement.getClassName()); } } } catch (ClassNotFoundException ex) { // Swallow and continue } return null; }
public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; FailureAnalyzers analyzers = null; configureHeadlessProperty();// 初始化SpringApplicationRunListener -》 SpringApplicationRunListeners listeners = getRunListeners(args);// 执行EventPublishingRunListener监听器,广播应用启动事件 listeners.starting(); try { ApplicationArguments applicationArguments = new DefaultApplicationArguments( args); ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);// 打印banner Banner printedBanner = printBanner(environment);// 初始化spring上下文 -》 context = createApplicationContext(); analyzers = new FailureAnalyzers(context);// 准备spring上下文 -》 prepareContext(context, environment, listeners, applicationArguments, printedBanner);// 刷新spring上下文 -》 refreshContext(context);// spring上下文初始化完毕加载其他applicationRunner afterRefresh(context, applicationArguments);// 执行监听器spring加载完成事件 listeners.finished(context, null); stopWatch.stop(); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass) .logStarted(getApplicationLog(), stopWatch); } return context; } catch (Throwable ex) { handleRunFailure(context, listeners, analyzers, ex); throw new IllegalStateException(ex); } }
启动springboot应用
org.springframework.boot.SpringApplication#getRunListeners 加载并初始化SpringApplicationRunListener
private SpringApplicationRunListeners getRunListeners(String[] args) { Class>[] types = new Class>[] { SpringApplication.class, String[].class }; return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances( SpringApplicationRunListener.class, types, this, args)); }
org.springframework.boot.SpringApplication#getSpringFactoriesInstances(java.lang.Class, java.lang.Class>[], java.lang.Object...)
private Collection extends T> getSpringFactoriesInstances(Classtype, Class>[] parameterTypes, Object... args) { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // Use names and ensure unique to protect against duplicates// 加载META-INF/spring.factories配置的SpringApplicationRunListener监听器 Set<String> names = new LinkedHashSet<String>( SpringFactoriesLoader.loadFactoryNames(type, classLoader));// 创建META-INF/spring.factories配置的SpringApplicationRunListener监听器对象 List instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); AnnotationAwareOrderComparator.sort(instances); return instances; }
从META-INF/spring.factories路径加载并初始化SpringApplicationRunListener
org.springframework.boot.SpringApplicationRunListeners#starting
public void starting() { for (SpringApplicationRunListener listener : this.listeners) { listener.starting(); } }
调用org.springframework.boot.SpringApplicationRunListener#starting方法。
org.springframework.boot.SpringApplication#createApplicationContext 用于创建应用程序上下文的策略方法。默认情况下,此方法将在返回到合适的默认值之前尊重任何显式设置的应用程序上下文或应用程序上下文类。
protected ConfigurableApplicationContext createApplicationContext() { Class> contextClass = this.applicationContextClass; if (contextClass == null) { try {// 创建基于annotation的上下文对象 contextClass = Class.forName(this.webEnvironment ? DEFAULT_WEB_CONTEXT_CLASS : DEFAULT_CONTEXT_CLASS); } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Unable create a default ApplicationContext, " + "please specify an ApplicationContextClass", ex); } } return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass); }
org.springframework.boot.SpringApplication#prepareContext 准备spring上下文
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) { context.setEnvironment(environment); postProcessApplicationContext(context);// 执行初始化器 =》 applyInitializers(context);// 执行监听器上下文准备事件 -》 listeners.contextPrepared(context); if (this.logStartupInfo) { logStartupInfo(context.getParent() == null); logStartupProfileInfo(context); } // Add boot specific singleton beans context.getBeanFactory().registerSingleton("springApplicationArguments", applicationArguments); if (printedBanner != null) { context.getBeanFactory().registerSingleton("springBootBanner", printedBanner); } // Load the sources Set<Object> sources = getSources(); Assert.notEmpty(sources, "Sources must not be empty");// 加载bean定义 =》 load(context, sources.toArray(new Object[sources.size()]));// 执行spring上线文加载完成事件 -》 listeners.contextLoaded(context); }
org.springframework.boot.SpringApplication#postProcessApplicationContext 在ApplicationContext中应用任何相关的后处理。子类可以根据需要应用额外的处理。
protected void postProcessApplicationContext(ConfigurableApplicationContext context) { if (this.beanNameGenerator != null) { context.getBeanFactory().registerSingleton( AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, this.beanNameGenerator); } if (this.resourceLoader != null) { if (context instanceof GenericApplicationContext) { ((GenericApplicationContext) context) .setResourceLoader(this.resourceLoader); } if (context instanceof DefaultResourceLoader) { ((DefaultResourceLoader) context) .setClassLoader(this.resourceLoader.getClassLoader()); } } }
org.springframework.boot.SpringApplication#applyInitializers 在上下文初始化之前加载ApplicationContextInitializer
protected void applyInitializers(ConfigurableApplicationContext context) { for (ApplicationContextInitializer initializer : getInitializers()) { Class> requiredType = GenericTypeResolver.resolveTypeArgument( initializer.getClass(), ApplicationContextInitializer.class); Assert.isInstanceOf(requiredType, context, "Unable to call initializer."); initializer.initialize(context); } }
执行org.springframework.context.ApplicationContextInitializer#initialize方法。
org.springframework.boot.SpringApplicationRunListeners#contextPrepared
public void contextPrepared(ConfigurableApplicationContext context) { for (SpringApplicationRunListener listener : this.listeners) { listener.contextPrepared(context); } }
执行org.springframework.boot.SpringApplicationRunListener#contextPrepared方法。
org.springframework.boot.SpringApplication#load
protected void load(ApplicationContext context, Object[] sources) { if (logger.isDebugEnabled()) { logger.debug( "Loading source " + StringUtils.arrayToCommaDelimitedString(sources)); }// 创建bean定义加载器 BeanDefinitionLoader loader = createBeanDefinitionLoader( getBeanDefinitionRegistry(context), sources); if (this.beanNameGenerator != null) {// 设置beanName生成器 loader.setBeanNameGenerator(this.beanNameGenerator); } if (this.resourceLoader != null) { loader.setResourceLoader(this.resourceLoader); } if (this.environment != null) { loader.setEnvironment(this.environment); }// 加载bean定义 =》 loader.load(); }
加载BeanDefinition
创建BeanDefinition注册器并创建BeanDefinitionLoader
org.springframework.boot.SpringApplication#getBeanDefinitionRegistry 获得BeanDefinition注册器
private BeanDefinitionRegistry getBeanDefinitionRegistry(ApplicationContext context) { if (context instanceof BeanDefinitionRegistry) { return (BeanDefinitionRegistry) context; } if (context instanceof AbstractApplicationContext) { return (BeanDefinitionRegistry) ((AbstractApplicationContext) context) .getBeanFactory(); } throw new IllegalStateException("Could not locate BeanDefinitionRegistry"); }
org.springframework.boot.SpringApplication#createBeanDefinitionLoader 创建BeanDefinitionLoader
protected BeanDefinitionLoader createBeanDefinitionLoader( BeanDefinitionRegistry registry, Object[] sources) { return new BeanDefinitionLoader(registry, sources); }
org.springframework.boot.BeanDefinitionLoader#BeanDefinitionLoader
BeanDefinitionLoader(BeanDefinitionRegistry registry, Object... sources) { Assert.notNull(registry, "Registry must not be null"); Assert.notEmpty(sources, "Sources must not be empty"); this.sources = sources;// 基于注解的BeanDefinitionReader this.annotatedReader = new AnnotatedBeanDefinitionReader(registry);// 基于xml方式的BeanDefinitionReader this.xmlReader = new XmlBeanDefinitionReader(registry); if (isGroovyPresent()) { this.groovyReader = new GroovyBeanDefinitionReader(registry); }// 基于classpath路径扫描BeanDefinition的scanner this.scanner = new ClassPathBeanDefinitionScanner(registry); this.scanner.addExcludeFilter(new ClassExcludeFilter(sources)); }
org.springframework.boot.BeanDefinitionLoader#load() 加载BeanDefinition
public int load() { int count = 0; for (Object source : this.sources) { count += load(source); } return count; }
org.springframework.boot.BeanDefinitionLoader#load(java.lang.Object)
private int load(Object source) { Assert.notNull(source, "Source must not be null"); if (source instanceof Class>) { return load((Class>) source); } if (source instanceof Resource) { return load((Resource) source); }// 注解扫描器加载bean定义 if (source instanceof Package) { return load((Package) source); } if (source instanceof CharSequence) { return load((CharSequence) source); } throw new IllegalArgumentException("Invalid source type " + source.getClass()); }
org.springframework.boot.BeanDefinitionLoader#load(java.lang.Class>) 加载配置类的BeanDefinition
private int load(Class> source) { if (isGroovyPresent()) { // Any GroovyLoaders added in beans{} DSL can contribute beans here if (GroovyBeanDefinitionSource.class.isAssignableFrom(source)) { GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class); load(loader); } } if (isComponent(source)) {// 注册带有@Configuration的配置类 this.annotatedReader.register(source); return 1; } return 0; }
org.springframework.boot.BeanDefinitionLoader#load(org.springframework.core.io.Resource) 加载配置文件的BeanDefinition
private int load(Resource source) { if (source.getFilename().endsWith(".groovy")) { if (this.groovyReader == null) { throw new BeanDefinitionStoreException( "Cannot load Groovy beans without Groovy on classpath"); }// 加载groovy文件的BeanDefinition return this.groovyReader.loadBeanDefinitions(source); }// 加载xml文件的BeanDefinition return this.xmlReader.loadBeanDefinitions(source); }
org.springframework.boot.BeanDefinitionLoader#load(java.lang.Package) 扫描package类型的BeanDefinition
private int load(Package source) { return this.scanner.scan(source.getName()); }
加载BeanDefinition相关的过程这里不做详细介绍了,可以查看spring源码解析系列相关文章
org.springframework.boot.SpringApplicationRunListeners#contextLoaded
public void contextLoaded(ConfigurableApplicationContext context) { for (SpringApplicationRunListener listener : this.listeners) { listener.contextLoaded(context); } }
执行org.springframework.boot.SpringApplicationRunListener#contextLoaded方法。
org.springframework.boot.SpringApplication#refreshContext 刷新ApplicationContext
private void refreshContext(ConfigurableApplicationContext context) { refresh(context); if (this.registerShutdownHook) { try { context.registerShutdownHook(); } catch (AccessControlException ex) { // Not allowed in some environments. } } }
org.springframework.boot.SpringApplication#refresh
protected void refresh(ApplicationContext applicationContext) { Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext); ((AbstractApplicationContext) applicationContext).refresh(); }
org.springframework.context.support.AbstractApplicationContext#refresh 刷新ApplicationContext,这里的逻辑在这里不详细做介绍,可以查看spring源码解析相关的文章有详细的介绍
org.springframework.boot.SpringApplication#afterRefresh
protected void afterRefresh(ConfigurableApplicationContext context, ApplicationArguments args) { callRunners(context, args); }
ApplicationContext刷新完毕后执行*runners。
private void callRunners(ApplicationContext context, ApplicationArguments args) { List<Object> runners = new ArrayList<Object>(); runners.addAll(context.getBeansOfType(ApplicationRunner.class).values()); runners.addAll(context.getBeansOfType(CommandLineRunner.class).values()); AnnotationAwareOrderComparator.sort(runners); for (Object runner : new LinkedHashSet<Object>(runners)) { if (runner instanceof ApplicationRunner) { callRunner((ApplicationRunner) runner, args); } if (runner instanceof CommandLineRunner) { callRunner((CommandLineRunner) runner, args); } } }
执行ApplicationRunner的run方法、CommandLineRunner的run方法
org.springframework.boot.SpringApplicationRunListeners#finished ApplicationContext刷新完成方法
public void finished(ConfigurableApplicationContext context, Throwable exception) { for (SpringApplicationRunListener listener : this.listeners) { callFinishedListener(listener, context, exception); } }
org.springframework.boot.SpringApplicationRunListeners#callFinishedListener
private void callFinishedListener(SpringApplicationRunListener listener, ConfigurableApplicationContext context, Throwable exception) { try { listener.finished(context, exception); } catch (Throwable ex) { if (exception == null) { ReflectionUtils.rethrowRuntimeException(ex); } if (this.log.isDebugEnabled()) { this.log.error("Error handling failed", ex); } else { String message = ex.getMessage(); message = (message != null) ? message : "no error message"; this.log.warn("Error handling failed (" + message + ")"); } } }
执行org.springframework.boot.SpringApplicationRunListener#finished方法。
public void setInitializers( Collection extends ApplicationContextInitializer>> initializers) { this.initializers = new ArrayList>(); this.initializers.addAll(initializers); }
添加ApplicationContextInitializer
public void addInitializers(ApplicationContextInitializer>... initializers) { this.initializers.addAll(Arrays.asList(initializers)); }
添加ApplicationContextInitialize
public void setListeners(Collection extends ApplicationListener>> listeners) { this.listeners = new ArrayList>(); this.listeners.addAll(listeners); }
添加ApplicationListeners
public void addListeners(ApplicationListener>... listeners) { this.listeners.addAll(Arrays.asList(listeners)); }
添加ApplicationListeners
org.springframework.boot.context.TypeExcludeFilter 实现了org.springframework.beans.factory.BeanFactoryAware接口
提供从BeanFactory加载并自动应用于SpringBootApplication扫描的排除类型筛选器。也可以直接使用@ComponentScan如下:@ComponentScan(excludeFilters = @Filter(type = FilterType)。自定义,class = TypeExcludeFilter.class)),实现应该提供一个用BeanFactory注册的子类,并覆盖match(MetadataReader, MetadataReaderFactory)方法。它们还应该实现一个有效的hashCode和equals方法,以便可以将它们用作Spring test的应用程序上下文缓存的一部分。注意TypeExcludeFilters是在应用程序生命周期的早期初始化的,它们通常不应该依赖于任何其他bean。它们主要用于内部支持spring-boot-test。
private BeanFactory beanFactory;
beanFactory
@Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; }
重写了org.springframework.beans.factory.BeanFactoryAware#setBeanFactory方法,设置beanFactory
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })@Retention(RetentionPolicy.RUNTIME)@Documented@Value("${local.server.port}")public @interface LocalServerPort {}
字段或方法/构造函数参数级别的注释,该参数注入运行时分配的HTTP端口。为@Value(“${local.server.port}”)提供了一个方便的替代方法。
说在最后
本次解析仅代表个人观点,仅供参考。
扫码进入技术微信群

钉钉技术群

qq技术群
