集团公司网站案例,网站投放广告赚钱吗,wordpress安装地址修改,分析 网站『SpringBoot 源码分析』run() 方法执行流程#xff1a;#xff08;2#xff09;刷新应用上下文-准备阶段
基于 2.2.9.RELEASE问题#xff1a;当方法进行了注释标记之后#xff0c;springboot 又是怎么注入到容器中并创建类呢#xff1f;
首先创建测试主程序
package …『SpringBoot 源码分析』run() 方法执行流程2刷新应用上下文-准备阶段
基于 2.2.9.RELEASE问题当方法进行了注释标记之后springboot 又是怎么注入到容器中并创建类呢
首先创建测试主程序
package com.lagou;SpringBootApplication//标注在类上说明这个类是SpringBoot的主配置类
public class SpringBootMytestApplication{public static void main(String[] args) {SpringApplication.run(SpringBootMytestApplication.class, args);}
}创建测试 Controller
package com.lagou.controller;RestController
public class TestController {RequestMapping(/test)public String test(){System.out.println(源码环境构建成功...);return 源码环境构建成功;}
}准备阶段
当准备完成应用上下文环境以及应用上下文以后需要为应用上下文做个准备阶段简单来说其实就是要配置应用上下文把需要的类装配上
public class SpringApplication {...public ConfigurableApplicationContext run(String... args) {...try {// 将运行时参数封装ApplicationArguments applicationArguments new DefaultApplicationArguments(args);// 构造应用上下文环境ConfigurableEnvironment environment prepareEnvironment(listeners, applicationArguments);// 处理需要忽略的 BeanconfigureIgnoreBeanInfo(environment);// 打印 bannerBanner printedBanner printBanner(environment);// 刷新应用上下文前的准备阶段context createApplicationContext();// 实例化 SpringBootExceptionReporter.class用来支持报告关于启动的错误exceptionReporters getSpringFactoriesInstances(SpringBootExceptionReporter.class,new Class[] { ConfigurableApplicationContext.class }, context);// 1. 刷新应用上下文前的准备阶段prepareContext(context, environment, listeners, applicationArguments, printedBanner);...}catch (Throwable ex) {...}...}
}在对应用上下文进行处理时主要执行了下面几步的装配
把上下文环境设置到应用上下文中执行容器后置处理把应用上下文交给 SpringApplication 初始化收集的 org.springframework.context.ApplicationContextInitializer 所有实现类进行初始化工作利用 org.springframework.boot.context.event.EventPublishingRunListener 向 org.springframework.context.ApplicationListener 发布容器准备好事件
public class SpringApplication {...// 完成属性设置 bean对象创建private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {// 1. 设置容器环境context.setEnvironment(environment);// 2. 执行容器后置处理postProcessApplicationContext(context);// 3. 执行一些初始化器applyInitializers(context); // 4. 向各个监听器发送容器已经准备好的事件listeners.contextPrepared(context);...}
}执行容器后置处理其实只是往 BeanFactory 添加了基础的转换器
public class SpringApplication {private BeanNameGenerator beanNameGenerator;private ResourceLoader resourceLoader;private boolean addConversionService true;...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());}}if (this.addConversionService) { // 1. 设置了转换器例如平时能把整数字符串转换为整形设置转换器context.getBeanFactory().setConversionService(ApplicationConversionService.getSharedInstance());}}
}执行一些初始化器就是遍历 org.springframework.context.ApplicationContextInitializer 执行 initialize() 方法
public class SpringApplication {...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.boot.context.event.EventPublishingRunListener 向 org.springframework.context.ApplicationListener 发布容器准备好事件
public class SpringApplication {...// 1. 当 ApplicationContext 构建完成时该方法被调用void contextPrepared(ConfigurableApplicationContext context) {for (SpringApplicationRunListener listener : this.listeners) {listener.contextPrepared(context);}}
}发布完监听之后从上下文中获取 IOC 工厂并设置允许 bean 定义被覆盖参数
public class SpringApplication {...// 完成属性设置 bean 对象创建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);}// 1. 获取 IOC 容器ConfigurableListableBeanFactory beanFactory context.getBeanFactory();// 将 main() 函数中的 args 参数封装成单例 Bean注册进容器beanFactory.registerSingleton(springApplicationArguments, applicationArguments);if (printedBanner ! null) {// 将 printedBanner 也封装成单例注册进容器beanFactory.registerSingleton(springBootBanner, printedBanner);}// 2. 设置允许 bean 定义被覆盖参数if (beanFactory instanceof DefaultListableBeanFactory) {((DefaultListableBeanFactory) beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}...}
}然后加载启动类并将启动类注入到容器当中然后发布容器已加载事件
public class SpringApplication {...// 完成属性设置 bean 对象创建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);}// 获取 IOC 容器ConfigurableListableBeanFactory beanFactory context.getBeanFactory();// 将 main() 函数中的 args 参数封装成单例 Bean注册进容器beanFactory.registerSingleton(springApplicationArguments, applicationArguments);if (printedBanner ! null) {// 将 printedBanner 也封装成单例注册进容器beanFactory.registerSingleton(springBootBanner, printedBanner);}// 设置允许 bean 定义被覆盖参数if (beanFactory instanceof DefaultListableBeanFactory) {((DefaultListableBeanFactory) beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}if (this.lazyInitialization) { // 是否需要进行懒加载这里不是context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());}// 1. 加载源这里拿到的是主类com.lagou.SpringBootMytestApplicationSetObject sources getAllSources();Assert.notEmpty(sources, Sources must not be empty);// 2. 加载我们的启动类将启动类注入容器 重点关注load(context, sources.toArray(new Object[0]));// 取出第一个元素就是主类要先实例化主类灌入容器中// 3. 发布容器已加载事件listeners.contextLoaded(context);}
}其中将启动类注入到容器当中是比较关键的一步首先先把 ApplicationContext 转换成 BeanDefinitionRegistry然后创建 bean 定义加载器
public class SpringApplication {...protected void load(ApplicationContext context, Object[] sources) {if (logger.isDebugEnabled()) {logger.debug(Loading source StringUtils.arrayToCommaDelimitedString(sources));}// 2. 创建 BeanDefinitionLoaderBeanDefinitionLoader loader createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources);...}private BeanDefinitionRegistry getBeanDefinitionRegistry(ApplicationContext context) {// 1. 将 ApplicationContext 转换成 BeanDefinitionRegistryif (context instanceof BeanDefinitionRegistry) {return (BeanDefinitionRegistry) context;}if (context instanceof AbstractApplicationContext) {return (BeanDefinitionRegistry) ((AbstractApplicationContext) context).getBeanFactory();}throw new IllegalStateException(Could not locate BeanDefinitionRegistry);}
}创建 BeanDefinitionLoader 主要是把 BeanDefinitionRegistry 以及主类的 sources 进行赋值初始化
public class SpringApplication {private final Object[] sources;private final AnnotatedBeanDefinitionReader annotatedReader;private final XmlBeanDefinitionReader xmlReader;private BeanDefinitionReader groovyReader;private final ClassPathBeanDefinitionScanner scanner;private ResourceLoader resourceLoader;...protected BeanDefinitionLoader createBeanDefinitionLoader(BeanDefinitionRegistry registry, Object[] sources) {// 1. 创建 bean 定义加载器return new BeanDefinitionLoader(registry, sources);}BeanDefinitionLoader(BeanDefinitionRegistry registry, Object... sources) {// 其中sources 就是主类 com.lagou.SpringBootMytestApplicationAssert.notNull(registry, Registry must not be null);Assert.notEmpty(sources, Sources must not be empty);this.sources sources;// 2. 注解形式的 Bean 定义读取器 比如Configuration Bean Component Controller Service等等this.annotatedReader new AnnotatedBeanDefinitionReader(registry);// 3. XML 形式的 Bean 定义读取器this.xmlReader new XmlBeanDefinitionReader(registry);if (isGroovyPresent()) {this.groovyReader new GroovyBeanDefinitionReader(registry);}// 4. 类路径扫描器this.scanner new ClassPathBeanDefinitionScanner(registry);// 5. 扫描器添加排除过滤器this.scanner.addExcludeFilter(new ClassExcludeFilter(sources));}
}创建 BeanDefinitionLoader 成功后就可以开始执行 load()这里主要是先把主类注册到 IOC 容器中去
public class SpringApplication {private BeanNameGenerator beanNameGenerator;...protected void load(ApplicationContext context, Object[] sources) {if (logger.isDebugEnabled()) {logger.debug(Loading source StringUtils.arrayToCommaDelimitedString(sources));}// 创建 BeanDefinitionLoaderBeanDefinitionLoader loader createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources);if (this.beanNameGenerator ! null) {loader.setBeanNameGenerator(this.beanNameGenerator);}if (this.resourceLoader ! null) {loader.setResourceLoader(this.resourceLoader);}if (this.environment ! null) {loader.setEnvironment(this.environment);}// 1. 执行 load()loader.load();}
}其中 load() 通过 AnnotatedBeanDefinitionReader 将主类 source 注册进 beanDefinitionMap 中
class BeanDefinitionLoader {private final AnnotatedBeanDefinitionReader annotatedReader;...int load() {int count 0;for (Object source : this.sources) {count load(source);}return count;}// 根据加载不同类型调用不同的方法private int load(Object source) {Assert.notNull(source, Source must not be null);// 1. 从 Class 加载if (source instanceof Class?) {return load((Class?) source);}...}private int load(Class? source) {// source 就是 class com.lagou.SpringBootMytestApplicationif (isGroovyPresent() GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {// Any GroovyLoaders added in beans{} DSL can contribute beans hereGroovyBeanDefinitionSource loader BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class);load(loader);}if (isComponent(source)) { // 判断方法有没有标记 Component 注解// 1. 将启动类的 BeanDefinition 注册进 beanDefinitionMapthis.annotatedReader.register(source);return 1;}return 0;}
}调用 register() 方法时真正会传到 doRegisterBean() 进行执行。首先会把主类转换成 AnnotatedGenericBeanDefinition然后获取主类的名称把名称和 AnnotatedGenericBeanDefinition 封装成 BeanDefinitionHolder 后注册到上下文中
public class AnnotatedBeanDefinitionReader {...public void register(Class?... componentClasses) {for (Class? componentClass : componentClasses) {registerBean(componentClass);}}public void registerBean(Class? beanClass) {doRegisterBean(beanClass, null, null, null, null);}private T void doRegisterBean(ClassT beanClass, Nullable String name,Nullable Class? extends Annotation[] qualifiers, Nullable SupplierT supplier,Nullable BeanDefinitionCustomizer[] customizers) {// 1. 把主类转换成 AnnotatedGenericBeanDefinition其中 beanClass 为 com.lagou.SpringBootMytestApplicationAnnotatedGenericBeanDefinition abd new AnnotatedGenericBeanDefinition(beanClass);if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}abd.setInstanceSupplier(supplier);ScopeMetadata scopeMetadata this.scopeMetadataResolver.resolveScopeMetadata(abd);abd.setScope(scopeMetadata.getScopeName());// 2. 获取类名 springBootMytestApplicationString beanName (name ! null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);if (qualifiers ! null) {for (Class? extends Annotation qualifier : qualifiers) {if (Primary.class qualifier) {abd.setPrimary(true);}else if (Lazy.class qualifier) {abd.setLazyInit(true);}else {abd.addQualifier(new AutowireCandidateQualifier(qualifier));}}}if (customizers ! null) {for (BeanDefinitionCustomizer customizer : customizers) {customizer.customize(abd);}}// 3. 封装成 BeanDefinitionHolder BeanDefinitionHolder definitionHolder new BeanDefinitionHolder(abd, beanName);definitionHolder AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);// 4. 注册到容器中 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);}
}注册到容器中简单而言就是调用 BeanDefinitionRegistry 把 BeanDefinitionHolder 的 name 和 AnnotatedGenericBeanDefinition 装配进去
public abstract class BeanDefinitionReaderUtils {...public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {// 1. 获取名称 springBootMytestApplicationString beanName definitionHolder.getBeanName();// 2. 注册到 IOC 容器中registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());String[] aliases definitionHolder.getAliases();if (aliases ! null) {String[] var4 aliases;int var5 aliases.length;for(int var6 0; var6 var5; var6) {String alias var4[var6];registry.registerAlias(beanName, alias);}}}
}最后会把 name 和 AnnotatedGenericBeanDefinition 存入到 beanDefinitionMap 中
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {...public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {Assert.hasText(beanName, Bean name must not be empty);Assert.notNull(beanDefinition, BeanDefinition must not be null);// 1. 先校验 beanDefinition 是否合法if (beanDefinition instanceof AbstractBeanDefinition) {try {((AbstractBeanDefinition)beanDefinition).validate();} catch (BeanDefinitionValidationException var8) {throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, Validation of bean definition failed, var8);}}BeanDefinition existingDefinition (BeanDefinition)this.beanDefinitionMap.get(beanName);if (existingDefinition ! null) {if (!this.isAllowBeanDefinitionOverriding()) {throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);}if (existingDefinition.getRole() beanDefinition.getRole()) {if (this.logger.isInfoEnabled()) {this.logger.info(Overriding user-defined bean definition for bean beanName with a framework-generated bean definition: replacing [ existingDefinition ] with [ beanDefinition ]);}} else if (!beanDefinition.equals(existingDefinition)) {if (this.logger.isDebugEnabled()) {this.logger.debug(Overriding bean definition for bean beanName with a different definition: replacing [ existingDefinition ] with [ beanDefinition ]);}} else if (this.logger.isTraceEnabled()) {this.logger.trace(Overriding bean definition for bean beanName with an equivalent definition: replacing [ existingDefinition ] with [ beanDefinition ]);}this.beanDefinitionMap.put(beanName, beanDefinition);} else {if (this.hasBeanCreationStarted()) {synchronized(this.beanDefinitionMap) {this.beanDefinitionMap.put(beanName, beanDefinition);ListString updatedDefinitions new ArrayList(this.beanDefinitionNames.size() 1);updatedDefinitions.addAll(this.beanDefinitionNames);updatedDefinitions.add(beanName);this.beanDefinitionNames updatedDefinitions;this.removeManualSingletonName(beanName);}} else {// 2. 再把 beanDefinition 放到 beanDefinitionMap 中this.beanDefinitionMap.put(beanName, beanDefinition);this.beanDefinitionNames.add(beanName);this.removeManualSingletonName(beanName);}this.frozenBeanDefinitionNames null;}if (existingDefinition null !this.containsSingleton(beanName)) {if (this.isConfigurationFrozen()) {this.clearByTypeCache();}} else {this.resetBeanDefinition(beanName);}}
}总结