当前位置:   article > 正文

Spring源码分析——启动流程_spring startupstep

spring startupstep

目标

追踪下面一段代码的流程:

AnnotationConfigApplicationContextDemo

  1. /**
  2. * @description
  3. * @date 2021-06-30 11:21
  4. **/
  5. public class AnnotationConfigApplicationContextDemo {
  6. public static void main(String[] args) {
  7. final AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SimpleConfig.class);
  8. User user = applicationContext.getBean(User.class);
  9. System.out.println("user:" + user);
  10. }
  11. }
  1. @Configuration
  2. public class SimpleConfig {
  3. @Bean
  4. public User user(){
  5. return new User("xgimi", 10);
  6. }
  7. }
  1. public class User {
  2. private String name;
  3. private Integer age;
  4. ...

流程

核心逻辑都在AnnotationConfigApplicationContext的带参构造器中:

  1. public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
  2. this();
  3. register(componentClasses);
  4. refresh();
  5. }

空构造器做了什么

先说答案: 两个事情,一是创建了BedefinitionReader、BeanDefinitionScanner,提供了扫描BeanDefinition的能力; 二是通过父类GenericApplicationContext的构造器创建了DefaultListableBeanFactory,提供底层的IOC能力。

初始化AnnotatedBeanDefinitionReader

  1. public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
  2. //注入registry,并且初始化Environment对象
  3. this(registry, getOrCreateEnvironment(registry));
  4. }

提供注册beanDefinition的能力

  1. public AnnotationConfigApplicationContext() {
  2. StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
  3. this.reader = new AnnotatedBeanDefinitionReader(this);
  4. createAnnotatedBeanDefReader.end();
  5. this.scanner = new ClassPathBeanDefinitionScanner(this);
  6. }

我们会在后面探究BeanDefinitionRegistry注册BeanDefinition的本质

获取环境对象 getOrCreateEnvironment这个方法进行环境的创建并获取:

  1. private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
  2. Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
  3. if (registry instanceof EnvironmentCapable) {
  4. return ((EnvironmentCapable) registry).getEnvironment();
  5. }
  6. return new StandardEnvironment();
  7. }

环境对象中包含了系统环境变量,自定义属性等内容。

通过构造器可以看到,AnnotatedBeanDefinitionReader底层维护了一个BeanDefinitionRegistry。实际上,他就是通过BeanDefinitionRegistry提供的注册能力,而AnnotationConfigApplicationContext本身就是一个BeanDefinitionRegistry;所以在调用AnnotatedBeanDefinitionReader构造器时,我们传入的就是AnnotationConfigApplicationContext:

初始化AnnotatedBeanDefinitionReader

初始化DefaultListableBeanFactory

首先探究以下AnnotationConfigApplicationContext和DefaultListableBeanFactory之间的关系:

1.png

实际上是组合关系,AnnotationConfigApplicationContext中大部分的能力,包括注册beanDefinition,依赖查找,依赖注入,都是通过DefaultListableBeanFactory通过的底层能力支持。

如何将配置类注册为BeanDefinition

在AnnotationConfigApplicationContext中:

  1. @Override
  2. public void register(Class<?>... componentClasses) {
  3. Assert.notEmpty(componentClasses, "At least one component class must be specified");
  4. StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register")
  5. .tag("classes", () -> Arrays.toString(componentClasses));
  6. //注册配置类
  7. this.reader.register(componentClasses);
  8. registerComponentClass.end();
  9. }

从上面代码可以看出,主要是调用了reader的register方法完成的注册,来看下这个方法的实现逻辑

  1. public void register(Class<?>... componentClasses) {
  2. for (Class<?> componentClass : componentClasses) {
  3. registerBean(componentClass);
  4. }
  5. }
  1. public void registerBean(Class<?> beanClass) {
  2. doRegisterBean(beanClass, null, null, null, null);
  3. }
  1. private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
  2. @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
  3. @Nullable BeanDefinitionCustomizer[] customizers) {
  4. //进来就先把class对象转为一个BeanDefinition,此时这个BeanDefinition中只有class信息和注解类上注解信息
  5. AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
  6. //处理@Conditional注解
  7. if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
  8. return;
  9. }
  10. //supplier会优先于所有的构造器和工厂方法进行类的实例化,但是不会影响属性设置
  11. abd.setInstanceSupplier(supplier);
  12. //处理scope,没有设置,默认返回singleton;@Scope("scopeName")会在这个方法中进行处理,获得scopeName
  13. ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
  14. abd.setScope(scopeMetadata.getScopeName());
  15. //创建beanName AnnotationBeanNameGenerator提供能力,但以接口入参为优先
  16. String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
  17. //将以下几个注解标注的值设置到abd中
  18. //1.@Lazy 2.@Primary 3.@Role 4.@DependesOn 5.@Description
  19. AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
  20. if (qualifiers != null) {
  21. for (Class<? extends Annotation> qualifier : qualifiers) {
  22. if (Primary.class == qualifier) {
  23. abd.setPrimary(true);
  24. }
  25. else if (Lazy.class == qualifier) {
  26. abd.setLazyInit(true);
  27. }
  28. else {
  29. abd.addQualifier(new AutowireCandidateQualifier(qualifier));
  30. }
  31. }
  32. }
  33. if (customizers != null) {
  34. for (BeanDefinitionCustomizer customizer : customizers) {
  35. customizer.customize(abd);
  36. }
  37. }
  38. //definitionHolder 保存的是beanDefinition和beanName(还可以有别名)
  39. BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
  40. //如果@Scope设置了代理,这里将会返回一个代理对象
  41. definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
  42. //将definitionHolder中的beanDefinition注册到registry对象中
  43. //DefaultListableBeanFactory.registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
  44. //最后的结果:DefaultListableBeanFactory中的beanDefinitionMap中存入一个beanDefinition,beanDefinitionNames中存入beanName
  45. BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
  46. }

综合上述代码,整理以下doRegisterBean的大致逻辑:

  1. 创建一个配置类对象的AnnotationBeanDefinition
  2. 通过AnnotationBeanDefinition解析类上面是否存在@Conditional注解,并判断是否满足注册的条件,如果不满足,则不进行注册
  3. 向abd中注册方法入参传入的 Supplier,后续可通过该接口实现bean的实例化
  4. 解析@Scope属性并注册到abd中
  5. 创建beanName
  6. 解析下面几个注解,并将对应属性注册到abd中
    1. @Lazy
    2. @Primary
    3. @Role
    4. @DependesOn
    5. @Description
  7. 创建一个beanDefinitionHolder保存abd和beanName,alias之间的对应关系
  8. 处理非单例Scope,返回一个代理,详见@Scope的处理过程
  9. BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);

我们来看下第9步,究竟是如何注册的:

BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
  1. public static void registerBeanDefinition(
  2. BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
  3. throws BeanDefinitionStoreException {
  4. // Register bean definition under primary name.
  5. String beanName = definitionHolder.getBeanName();
  6. registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
  7. // Register aliases for bean name, if any.
  8. String[] aliases = definitionHolder.getAliases();
  9. if (aliases != null) {
  10. for (String alias : aliases) {
  11. //TODO
  12. registry.registerAlias(beanName, alias);
  13. }
  14. }
  15. }

可以看到,实际进行了两部分注册:

  1. 注册beanName
  2. 注册别名

其中registry都是AnnotationConfigApplicationContext 先看一下registerBeanDefinition方法的实现:

2.png

如下所示,我们调用的应该是GenericApplicationContext中的实现方法,进去看看:

3.png

结果发现还是使用的DefaultListableBeanFactory进行注册的,这也论证了我们上面关于DefaultListableBeanFactory和AnnotationConfigApplicationContext之间关系的结论。来看看DefaultListableBeanFactory中究竟是怎么实现的吧:

  1. @Override
  2. public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
  3. throws BeanDefinitionStoreException {
  4. Assert.hasText(beanName, "Bean name must not be empty");
  5. Assert.notNull(beanDefinition, "BeanDefinition must not be null");
  6. if (beanDefinition instanceof AbstractBeanDefinition) {
  7. try {
  8. ((AbstractBeanDefinition) beanDefinition).validate();
  9. }
  10. catch (BeanDefinitionValidationException ex) {
  11. throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
  12. "Validation of bean definition failed", ex);
  13. }
  14. }
  15. BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
  16. if (existingDefinition != null) {
  17. if (!isAllowBeanDefinitionOverriding()) {
  18. throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
  19. }
  20. else if (existingDefinition.getRole() < beanDefinition.getRole()) {
  21. // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
  22. if (logger.isInfoEnabled()) {
  23. logger.info("Overriding user-defined bean definition for bean '" + beanName +
  24. "' with a framework-generated bean definition: replacing [" +
  25. existingDefinition + "] with [" + beanDefinition + "]");
  26. }
  27. }
  28. else if (!beanDefinition.equals(existingDefinition)) {
  29. if (logger.isDebugEnabled()) {
  30. logger.debug("Overriding bean definition for bean '" + beanName +
  31. "' with a different definition: replacing [" + existingDefinition +
  32. "] with [" + beanDefinition + "]");
  33. }
  34. }
  35. else {
  36. if (logger.isTraceEnabled()) {
  37. logger.trace("Overriding bean definition for bean '" + beanName +
  38. "' with an equivalent definition: replacing [" + existingDefinition +
  39. "] with [" + beanDefinition + "]");
  40. }
  41. }
  42. this.beanDefinitionMap.put(beanName, beanDefinition);
  43. }
  44. else {
  45. if (hasBeanCreationStarted()) {
  46. // Cannot modify startup-time collection elements anymore (for stable iteration)
  47. synchronized (this.beanDefinitionMap) {
  48. this.beanDefinitionMap.put(beanName, beanDefinition);
  49. List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
  50. updatedDefinitions.addAll(this.beanDefinitionNames);
  51. updatedDefinitions.add(beanName);
  52. this.beanDefinitionNames = updatedDefinitions;
  53. removeManualSingletonName(beanName);
  54. }
  55. }
  56. else {
  57. // Still in startup registration phase
  58. // 主要看这里
  59. this.beanDefinitionMap.put(beanName, beanDefinition);
  60. this.beanDefinitionNames.add(beanName);
  61. removeManualSingletonName(beanName);
  62. }
  63. this.frozenBeanDefinitionNames = null;
  64. }
  65. if (existingDefinition != null || containsSingleton(beanName)) {
  66. resetBeanDefinition(beanName);
  67. }
  68. else if (isConfigurationFrozen()) {
  69. clearByTypeCache();
  70. }
  71. }

上述的代码,先检查了容器中是否已经注册过了该bd,再检查了是否正在注册该db;而我们是第一次注册,所以走的核心分支就是第59行开始的else分支。做了下面几件事情:

  1. 向beanDefinitionMap中放入了beanName为key的beanDefinition
  2. 向beanDefinitionNames中放入了beanName
  3. 如果manualSingletonNames中存在beanName,将其移除

为什么要单独维护一个beanDefinitionNames?主要是因为beanDefinitionMap是无序的,而beanDefinitionNames是一个ArrayList,是有序的,可以保存bd的注册顺序

refresh方法都做了什么

1.prepareRefresh

  1. protected void prepareRefresh() {
  2. // Switch to active.
  3. this.startupDate = System.currentTimeMillis();
  4. this.closed.set(false);
  5. this.active.set(true);
  6. if (logger.isDebugEnabled()) {
  7. if (logger.isTraceEnabled()) {
  8. logger.trace("Refreshing " + this);
  9. }
  10. else {
  11. logger.debug("Refreshing " + getDisplayName());
  12. }
  13. }
  14. // Initialize any placeholder property sources in the context environment.
  15. //非web环境下默认是空的实现
  16. initPropertySources();
  17. // Validate that all properties marked as required are resolvable:
  18. // see ConfigurablePropertyResolver#setRequiredProperties
  19. getEnvironment().validateRequiredProperties();
  20. // Store pre-refresh ApplicationListeners...
  21. if (this.earlyApplicationListeners == null) {
  22. this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
  23. }
  24. else {
  25. // Reset local application listeners to pre-refresh state.
  26. this.applicationListeners.clear();
  27. this.applicationListeners.addAll(this.earlyApplicationListeners);
  28. }
  29. // Allow for the collection of early ApplicationEvents,
  30. // to be published once the multicaster is available...
  31. this.earlyApplicationEvents = new LinkedHashSet<>();
  32. }

预刷新阶段主要做了一下几件事情:

  • 提供initPropertySources()扩展方法供容器进行外部资源加载,在AnnotationContextApplicationContext中默认是空实现
  • getEnvironment().validateRequiredProperties();进行必填属性的校验,是AbstractPropertyResolver这个接口提供的能力,Environment对象是这个接口的实现。
  1. @Override
  2. public void validateRequiredProperties() {
  3. MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
  4. for (String key : this.requiredProperties) {
  5. if (this.getProperty(key) == null) {
  6. ex.addMissingRequiredProperty(key);
  7. }
  8. }
  9. if (!ex.getMissingRequiredProperties().isEmpty()) {
  10. throw ex;
  11. }
  12. }

默认容器中是没有必须存在的属性的,如果需要添加该校验,则通过beanFactory获取到Environment,然后再进行设置:

  1. AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
  2. applicationContext.register(SimpleConfig.class);
  3. applicationContext.getEnvironment().setRequiredProperties("system");
  4. applicationContext.refresh();

实际上是调用的AbstractPropertyResolver类的下面方法

  1. //设置必须存在的属性
  2. @Override
  3. public void setRequiredProperties(String... requiredProperties) {
  4. Collections.addAll(this.requiredProperties, requiredProperties);
  5. }

requiredProperties是一个LinkedHashSet

	private final Set<String> requiredProperties = new LinkedHashSet<>();
  • 在容器中创建earlyApplicationListeners、earlyApplicationEvents

2.obtainFreshBeanFactory

通过该方法的返回值可以判断他就是获取了容器中内置的ConfigurableListableBeanFactory,我们来看他具体是怎么获取的:

  1. protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
  2. refreshBeanFactory();
  3. return getBeanFactory();
  4. }

其中:getBeanFactory()方法是很好理解的,他就是把GenericApplicationContext中保存的DefaultListableBeanFactory返回,这个DefaultListableBeanFactor是在GenericApplicationContext的空构造器中实例化的。 我们看下refreshBeanFactory()中做了什么:

  1. @Override
  2. protected final void refreshBeanFactory() throws IllegalStateException {
  3. //内部容器只允许refresh一次
  4. if (!this.refreshed.compareAndSet(false, true)) {
  5. throw new IllegalStateException(
  6. "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
  7. }
  8. this.beanFactory.setSerializationId(getId());
  9. }

主要是对refreshed进行了cas修改,以保证容器只会被刷新一次

3.prepareBeanFactory(beanFactory)

容器的准备阶段

  1. protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  2. // Tell the internal bean factory to use the context's class loader etc.
  3. beanFactory.setBeanClassLoader(getClassLoader());
  4. if (!shouldIgnoreSpel) {
  5. //设置el表达式解析器(#{...})
  6. beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
  7. }
  8. //设置属性解析器PropertyEditorRegistrar
  9. beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
  10. // Configure the bean factory with context callbacks.
  11. //为容器中添加一个ApplicationContextAwareProcessor,这是容器中添加的第一个BeanPostProcessor
  12. //ApplicationContextAwareProcessor的作用:
  13. //判断bean是否实现了下面的Aware接口,如果实现了,这把相应的内建bean或单例对象赋给该bean
  14. //1.EnvironmentAware -> applicationContext.getEnvironment()
  15. //2.EmbeddedValueResolverAware -> embeddedValueResolver
  16. //3.ResourceLoaderAware -> applicationContext
  17. //4.ApplicationEventPublisherAware -> applicationContext
  18. //5.MessageSourceAware -> applicationContext
  19. //6.ApplicationContextAware -> applicationContext
  20. //7.ApplicationStartupAware -> applicationContext.getApplicationStartup()
  21. beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
  22. beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
  23. beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
  24. beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
  25. beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
  26. beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
  27. beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
  28. beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);
  29. //添加容器内建依赖
  30. // BeanFactory interface not registered as resolvable type in a plain factory.
  31. // MessageSource registered (and found for autowiring) as a bean.
  32. beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
  33. beanFactory.registerResolvableDependency(ResourceLoader.class, this);
  34. beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
  35. beanFactory.registerResolvableDependency(ApplicationContext.class, this);
  36. // Register early post-processor for detecting inner beans as ApplicationListeners.
  37. // 处理实现了ApplicationListener接口的bean
  38. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
  39. // Detect a LoadTimeWeaver and prepare for weaving, if found.
  40. if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
  41. beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
  42. // Set a temporary ClassLoader for type matching.
  43. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
  44. }
  45. // Register default environment beans.
  46. // 在beanFactory中注入下面的单例对象
  47. if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
  48. beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
  49. }
  50. if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
  51. beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
  52. }
  53. if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
  54. beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
  55. }
  56. if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
  57. beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
  58. }
  59. }
  • 设置ClassLoader
  • 设置el表达式解析器
  • 设置PropertyEditorRegistrar
  • 添加一个ApplicationContextAwareProcessor判断bean是否实现了下面的Aware接口,如果实现了,这把相应的内建bean或单例对象赋给该bean 1.EnvironmentAware -> applicationContext.getEnvironment() 2.EmbeddedValueResolverAware -> embeddedValueResolver 3.ResourceLoaderAware -> applicationContext 4.ApplicationEventPublisherAware -> applicationContext 5.MessageSourceAware -> applicationContext 6.ApplicationContextAware -> applicationContext 7.ApplicationStartupAware -> applicationContext.getApplicationStartup()
  • ignoreDependencyInterface:在自动装配时忽略下面这些接口,实现了下述接口,可以通过set方法接受aware回调传入的值进行装配
  1. beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
  2. beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
  3. beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
  4. beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
  5. beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
  6. beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
  7. beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);
  • 添加容器内建依赖。容器的内建依赖会保存在resolvableDependencies,支持通过类型进行依赖注入,主要解决的问题是同一种类型存在多个依赖对象,spring在自动装配的时候会报错,但是如果在resolvableDependencies中指定了具体类型的装配对象,则直接可以使用指定对象。spring容器中存在多个BeanFactory等类型的对歌对象,所以这里将其依赖对象指定,避免报错。我们也可以通过自定义BeanFactoryPostProcessor获取Beanfactory,然后指定自己的类型-依赖对象关系。
  1. beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
  2. beanFactory.registerResolvableDependency(ResourceLoader.class, this);
  3. beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
  4. beanFactory.registerResolvableDependency(ApplicationContext.class, this);
  • 添加ApplicationListenerDetector,DestructionAwareBeanPostProcessor:bean曝光前回调,在对外提供bean实例之前,可以返回代理对象替换beanMergedBeanDefinitionPostProcessor
class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {
  • 直接注册四个单例对象
  1. // Register default environment beans.
  2. // 在beanFactory中注入下面的单例对象
  3. if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
  4. beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
  5. }
  6. if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
  7. beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
  8. }
  9. if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
  10. beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
  11. }
  12. if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
  13. beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
  14. }

4.postProcessBeanFactory

预留的扩展方法,默认没有实现

5.invokeBeanFactoryPostProcessors(beanFactory)

关于BeanFactoryPostProcesso,我们先了解下面两点:

  1. 注册BeanFactoryPostProcessor:ConfigurableApplicationContext#addBeanFactoryPostProcessor
  2. BeanFactoryPostProcessor的作用:
  1. @FunctionalInterface
  2. public interface BeanFactoryPostProcessor {
  3. /**
  4. * 在所有beanDefinition已经加载,且没有Bean实例化之前,修改application的内置beanFactory
  5. * 该方法可以支持修改beanDefinition的属性配置,甚至可以提前初始化bean
  6. * Modify the application context's internal bean factory after its standard
  7. * initialization. All bean definitions will have been loaded, but no beans
  8. * will have been instantiated yet. This allows for overriding or adding
  9. * properties even to eager-initializing beans.
  10. * @param beanFactory the bean factory used by the application context
  11. * @throws org.springframework.beans.BeansException in case of errors
  12. */
  13. void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
  14. }

简而言之,就是在第3步将内置beanfactory准备完毕之后。给用户一次机会再获取到beanFactory 接下来我们研究invokeBeanFactoryPostProcessors的流程,这里默认容器中是不会注册BeanFactoryPostProcessor的,但是这个方法还有其他的作用

  1. protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
  2. PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
  3. // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
  4. // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
  5. if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
  6. beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
  7. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
  8. }
  9. }

getBeanFactoryPostProcessors()

  1. public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
  2. return this.beanFactoryPostProcessors;
  3. }

PostProcessorRegistrationDelegate

  1. public static void invokeBeanFactoryPostProcessors(
  2. ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
  3. // WARNING: Although it may appear that the body of this method can be easily
  4. // refactored to avoid the use of multiple loops and multiple lists, the use
  5. // of multiple lists and multiple passes over the names of processors is
  6. // intentional. We must ensure that we honor the contracts for PriorityOrdered
  7. // and Ordered processors. Specifically, we must NOT cause processors to be
  8. // instantiated (via getBean() invocations) or registered in the ApplicationContext
  9. // in the wrong order.
  10. //
  11. // Before submitting a pull request (PR) to change this method, please review the
  12. // list of all declined PRs involving changes to PostProcessorRegistrationDelegate
  13. // to ensure that your proposal does not result in a breaking change:
  14. // https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
  15. // Invoke BeanDefinitionRegistryPostProcessors first, if any.
  16. Set<String> processedBeans = new HashSet<>();
  17. if (beanFactory instanceof BeanDefinitionRegistry) {
  18. BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
  19. List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
  20. List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
  21. for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
  22. if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
  23. BeanDefinitionRegistryPostProcessor registryProcessor =
  24. (BeanDefinitionRegistryPostProcessor) postProcessor;
  25. registryProcessor.postProcessBeanDefinitionRegistry(registry);
  26. registryProcessors.add(registryProcessor);
  27. }
  28. else {
  29. regularPostProcessors.add(postProcessor);
  30. }
  31. }
  32. // Do not initialize FactoryBeans here: We need to leave all regular beans
  33. // uninitialized to let the bean factory post-processors apply to them!
  34. // Separate between BeanDefinitionRegistryPostProcessors that implement
  35. // PriorityOrdered, Ordered, and the rest.
  36. List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
  37. // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
  38. String[] postProcessorNames =
  39. beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  40. for (String ppName : postProcessorNames) {
  41. if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
  42. currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  43. processedBeans.add(ppName);
  44. }
  45. }
  46. sortPostProcessors(currentRegistryProcessors, beanFactory);
  47. registryProcessors.addAll(currentRegistryProcessors);
  48. invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
  49. currentRegistryProcessors.clear();
  50. // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
  51. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  52. for (String ppName : postProcessorNames) {
  53. if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
  54. currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  55. processedBeans.add(ppName);
  56. }
  57. }
  58. sortPostProcessors(currentRegistryProcessors, beanFactory);
  59. registryProcessors.addAll(currentRegistryProcessors);
  60. invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
  61. currentRegistryProcessors.clear();
  62. // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
  63. boolean reiterate = true;
  64. while (reiterate) {
  65. reiterate = false;
  66. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
  67. for (String ppName : postProcessorNames) {
  68. if (!processedBeans.contains(ppName)) {
  69. currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
  70. processedBeans.add(ppName);
  71. reiterate = true;
  72. }
  73. }
  74. sortPostProcessors(currentRegistryProcessors, beanFactory);
  75. registryProcessors.addAll(currentRegistryProcessors);
  76. invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
  77. currentRegistryProcessors.clear();
  78. }
  79. // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
  80. invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
  81. invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
  82. }
  83. else {
  84. // Invoke factory processors registered with the context instance.
  85. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
  86. }
  87. // Do not initialize FactoryBeans here: We need to leave all regular beans
  88. // uninitialized to let the bean factory post-processors apply to them!
  89. String[] postProcessorNames =
  90. beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
  91. // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
  92. // Ordered, and the rest.
  93. List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
  94. List<String> orderedPostProcessorNames = new ArrayList<>();
  95. List<String> nonOrderedPostProcessorNames = new ArrayList<>();
  96. for (String ppName : postProcessorNames) {
  97. if (processedBeans.contains(ppName)) {
  98. // skip - already processed in first phase above
  99. }
  100. else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
  101. priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
  102. }
  103. else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
  104. orderedPostProcessorNames.add(ppName);
  105. }
  106. else {
  107. nonOrderedPostProcessorNames.add(ppName);
  108. }
  109. }
  110. // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
  111. sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
  112. invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
  113. // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
  114. List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
  115. for (String postProcessorName : orderedPostProcessorNames) {
  116. orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
  117. }
  118. sortPostProcessors(orderedPostProcessors, beanFactory);
  119. invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
  120. // Finally, invoke all other BeanFactoryPostProcessors.
  121. List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
  122. for (String postProcessorName : nonOrderedPostProcessorNames) {
  123. nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
  124. }
  125. invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
  126. // Clear cached merged bean definitions since the post-processors might have
  127. // modified the original metadata, e.g. replacing placeholders in values...
  128. beanFactory.clearMetadataCache();
  129. }

主要流程:

  1. 创建两个list分别保存BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor
  2. 将自定义注册的BeanFactoryPostProcessor按照类型分别存入regularPostProcessors或者registryProcessors,并且:如果是BeanDefinitionRegistryPostProcessor,则直接调用其postProcessBeanDefinitionRegistry方法
  3. 创建一个新的列表来保存容器内置的BeanDefinitionRegistryPostProcessor
  4. 通过BeanDefinitionRegistryPostProcessor类型以及PriorityOrdered获取容器中对对应的bean,放入currentRegistryProcessors,并将名字放入processedBeans,表示已经执行。这里会得到一个:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
  5. 将currentRegistryProcessors排序,并且放入registryProcessors
  6. 遍历执行currentRegistryProcessors中的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
  7. 这里会执行internalConfigurationAnnotationProcessor的回调方法,这个类后续会专项研究,其结果就是把配置类中@Bean方法对应的类加载到容器中注册为bd
  8. 清空currentRegistryProcessors
  9. 重复4-8,调用的是实现了Ordered接口的BeanDefinitionRegistryPostProcessor
  10. 重复4-8,调用没有实现排序接口的BeanDefinitionRegistryPostProcessor
  11. 通过上面的操作,所有的BeanDefinitionRegistryPostProcessor都加入了registryProcessors,所有的自定义BeanFactoryPostProcessor都加入了regularPostProcessors。执行他们的postProcessBeanFactory方法
  12. 现在还有容器内置的BeanFactoryPostProcessor没有处理,也按照PriorityOrdered,Ordered,nonOrdered的顺序依次加载并调用他们的postProcessBeanFactory方法

6.initMessageSource

MessageSource列为专题讨论

7.initApplicationEventMulticaster()

事件广播机制列为专题讨论

8.onRefresh

截止到这里,整个beanfactory已经准备就绪了。剩下的就是容器中的bean的处理了,再此之前,可以通过onFresh方法执行回调。例如在SpringBoot中,就是通过这个方法进行的嵌入式web容器启动

9.registerListeners()

  1. 注册容器内置的listener
  2. 注册实现了ApplicationListener接口的类

10.inishBeanFactoryInitialization(beanFactory)

实例化所有非懒加载的单例bean 这个流程又是非常复杂的逻辑,我们放在第二章进行讨论

总结

经过上述的步骤,spring容器已经初始化完成,beanFactory准备就绪。ApplicatiionContext提供的扩展特性:事件机制,资源,AOP等能力也已经初始化完成

最后

我想,可能还有很多人在今年刚过去的金三银四春招中保持着观望的形势,害怕自己的能力不够,或者是安于现状,觉得目前拿着几千的月薪觉得能够接受,那么你就要注意了,这是非常危险的!

我们身为技术人员,最怕的就是安于现状,一直在原地踏步,那么你可能在30岁就会迎来自己的职业危机,因为你工作这么久提升的只有自己的年龄,技术还是万年不变!

如果你想在未来能够自我突破,圆梦大厂,那或许以上这些Java面试题资料,你需要阅读阅读,希望能够对你的职业发展有所帮助。

Java进阶之路群,找管理员获取哦!

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/609356
推荐阅读
相关标签
  

闽ICP备14008679号