spring源码分析 - AnnotationConfigApplicationContext启动之refresh

前言

我们在使用spring framework时一般都喜欢按照以下方式写启动

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
而我们的AnnotationConfigApplicationContext的内容如下
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
   // 构造DefaultListableBeanFactory、AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner
   this();
   register(componentClasses);
   refresh();
}

在前面的文章中我们介绍了AnnotationConfigApplicationContext 里reader、scaner、AppConfig.class的beandefiniton如何建创,这里我主要介绍一下refresh()方法里主要逻辑

refresh()方法代码内容

从以下代码内容看其实主要调用的各个方法,我们来深入了解一下具体功能,具体方法里的代码内容不展示,主要说明各个方法功能

public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");     
      prepareRefresh();      
       ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();       
      prepareBeanFactory(beanFactory);
      try {          
         postProcessBeanFactory(beanFactory);
         StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
         invokeBeanFactoryPostProcessors(beanFactory);   
         registerBeanPostProcessors(beanFactory);
         beanPostProcess.end(); 
         initMessageSource(); 
         initApplicationEventMulticaster();  
         onRefresh();   
         registerListeners(); 
         finishBeanFactoryInitialization(beanFactory); 
         finishRefresh();
      }
      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         } 
         destroyBeans(); 
         cancelRefresh(ex); 
         throw ex;
      }
      finally {         
         resetCommonCaches();
         contextRefresh.end();
      }
   }
}

prepareRefresh逻辑

1.initPropertySources
初始化系统属性信息,主要是向Environment中保存,如果我们启动的是webapplicationcontext的话主要生成MutablePropertySources对象StandardServletEnvironment的属性propertySources,主要向其中放如servlet的servletContextInitParams和servletConfigInitParams两种数据,数据是真正保存在MutablePropertySources的propertySourceList中,它的定义如下:
List> propertySourceList = new CopyOnWriteArrayList<>();

2.getEnvironment().validateRequiredProperties();

  • 检查1中加载的环境属性值是否有空值的情况,如有抛出异常
  • 生成beanfactory的属性earlyApplicationListeners,new
    LinkedHashSet<>(this.applicationListeners)
  • 生成beanfactory的属性earlyApplicationEvents = new LinkedHashSet<>()

obtainFreshBeanFactory()逻辑

1.生成并设定beanfactory的serializationId
2.返回beanfactory

prepareBeanFactory逻辑

  1. 设定beanfactory的beanLassLoader

  2. 设定beanfactory的beanExpressionResolver,主要是 通过new SpelExpressionParser(new SpelParserConfiguration(null,beanClassLoader))

  3. 向beanfactory的属性propertyEditorRegistrars加入new
    ResourceEditorRegistrar(this, getEnvironment(),主用于注册编辑转换器

  4. 向beanfactory的属性ignoredDependencyInterfaces加入EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、 ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware、ApplicationStartupAware
    主要用于忽略的依赖和自动注入的class,主要通过beanFactory.ignoreDependencyInterface个方法来实现,在系统开发时如果某个class不想作为自动依赖注入,可以将此作为扩展点

  5. 向beanfactory的属性resolvableDependencies加入BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
    主要用于向beanfactory放入自动依赖注入时可以注入的类型,主要通过beanFactory.registerResolvableDependency方法实现,在系统开发也可以作为一个扩展点

  6. 向beanfactory的属性beanPostProcessors加入ApplicationListenerDetector对象
    这个对象主要用于bean对像初始化后和销毁之前的事件广播,主要通过postProcessAfterInitialization、postProcessBeforeDestruction这两个方法调用,主要是从beanfactory的属性中applicationEventMulticaster加入或删除,这样前提条件如果bean集成了ApplicationListener接口类对象

  7. 向beanfactory的属性singletonObjects加入以下单例bean,及registeredSingletons放入已经实例的名字

       ENVIRONMENT_BEAN_NAME:    StandardEnvironment
       SYSTEM_PROPERTIES_BEAN_NAME: getEnvironment().getSystemProperties()
       SYSTEM_ENVIRONMENT_BEAN_NAME:  getEnvironment().getSystemEnvironment()
       APPLICATION_STARTUP_BEAN_NAME :  getApplicationStartup()           
    

postProcessBeanFactory逻辑

这里主要用web有关的逻辑,主要功能如下:

  1. 向beanfactory的属性beanPostProcessors加入ServletContextAwareProcessor
  2. 向beanfactory的属性put加入以下内容
    SCOPE_REQUEST:RequestScope
    SCOPE_SESSION:SessionScope
    SCOPE_APPLICATION:ServletContextScope(sc)
  3. 向beanfactory的属性resolvableDependencies加入可自动依赖类型
beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
if (jsfPresent) {
   FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
}

invokeBeanFactoryPostProcessors逻辑

  1. .从beanfactory的属性beanFactoryPostProcessors获取BeanDefinitionRegistryPostProcessor对象并执行其postProcessBeanDefinitionRegistry方法
    在启动阶段beanFactoryPostProcessors没有内容

  2. 从factory的属性中beanDefinitionNames、manualSingletonNames找出是BeanDefinitionRegistryPostProcessor类型的beanname
    在启动阶段只有ConfigurationClassPostProcessor的beandefinition满足条件的

  3. 从2找中满足条件beanname,在判断这个是否为PriorityOrdered子类,若是调用beanfactory.getBean生成bean,并放入变量currentRegistryProcessors中,并在processedBeans加入beanname
    这里getBean逻辑细节单节整理,主要是参考beandefinition的信息生成bean

  4. 对currentRegistryProcessors中的bean按照dependencyComparator进行排序,并加入registryProcessors变量中

  5. 调用执行postProcessBeanDefinitionRegistry方法

  • 启动阶段主要是执行ConfigurationClassPostProcessor类的postProcessBeanDefinitionRegistry方法,然后内部在调用processConfigBeanDefinitions方法

  • 从factory的属性中beanDefinitionMap中得到有@Configuration的类,主要是通过ConfigurationClassUtils.checkConfigurationClassCandidate方法查找,并对beandefinition设定如下内容:

if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
   beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
} 
else if (config != null || isConfigurationCandidate(metadata)) {
   beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
else {
   return false;
} 
Integer order = getOrder(metadata);
if (order != null) {
   beanDef.setAttribute(ORDER_ATTRIBUTE, order);
}
  • 然后对找到所有@Configuration类进行排序,按照beandefinition的order值排序,如果order没有设定取Integer.MAX_VALUE

  • 获取factory的属性singletonObjects获取org.springframework.context.annotation.internalConfigurationBeanNameGenerator类型bean,并赋给成员属性componentScanBeanNameGenerator、importBeanNameGenerator,在启动阶段factory中没有此类型的bean

  • 给environment属性设定StandardEnvironment

  • 创建ConfigurationClassParser类的对象parser

  • 执行parser对象的parse()方法进行解析含有@Configuration类的beandefinition,在执行processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER)这个方法:

    1. 如果beandefinition的类有@condition注解,直接返回

    2. 调用asSourceClass方法生成SouceClass对象sourceClass

      a) 解析beandefinition类上各个注解有效性,主要通过测试注解类包含的方法返回类型为(type == Class.class || type == Class[].class || type.isEnum())是否抛异常,主要是通过调用AttributeMethods.forAnnotationType(annotation.annotationType()).validate(annotation)来实现
      b) 如果2中没有抛出异常,生成SourceClass对象

    3.执行doProcessConfigurationClass(configClass, sourceClass, filter)方法

     a). 判断注解类是否为Component.class,在通过执行processMemberClasses(configClass,sourceClass,filter)方法判断内部类是否不是接口、是否为@Component、@ComponentScan、@Import、@ImportResouce其中一个、是否有@Bean注解,若满足条件之一对内部注解类按照这里的1、2、3、4的步骤递归调用执行
     b).  解析@PropertySource,通过通过以下方法
          AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class))
            i.获取@PropertySource和@PropertySources的value、encoding、name、ignoreResourceNotFoud属性数据
            ii.根据value的内容,生成value内容的propertySource对象,放入parse对象environment属性中的propertySources属性
            iii.将value内容放入parse对象的propertySourceNames属性中
     c). 解析@CompoentScan
         i. 通过调用AnnotationConfigUtils得到注解的属性值Set componentScans,主要有value、basePackages、basePackageClasses、resourcePattern(默认值:**/*.class)等相关属性
     		componentScan = {AnnotationAttributes@2077}  size = 11
     		 "basePackageClasses" -> {Class[0]@2092} 
     		 "basePackages" -> {String[1]@2094} ["com.test"]
     		 "excludeFilters" -> {AnnotationAttributes[0]@2096} 
     		 "includeFilters" -> {AnnotationAttributes[0]@2098} 
     		 "lazyInit" -> {Boolean@2100} false
     		 "nameGenerator" -> {Class@846} "interface org.springframework.beans.factory.support.BeanNameGenerator"
     		 "resourcePattern" -> "**/*.class"
     		 "scopeResolver" -> {Class@849} "class org.springframework.context.annotation.AnnotationScopeMetadataResolver"
     		 "scopedProxy" -> {ScopedProxyMode@2106} "DEFAULT"
     		 "useDefaultFilters" -> {Boolean@2108} true
     		 "value" -> {String[1]@2109} ["com.test"]
     		 如果useDefaultFilters为true,设定defaultFilter,可以为@Component、@Named、@ManagedBean
     	ii. 执行parse.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()),componentScanParser为ComponentScanAnnotationParser实例化对象,这部分逻辑单独整理,主要扫描类也生成beandefition有关逻辑
    **找到相关类通过以下代码来扫描,主要根据basepackage属性**
    *****************************************************************************
     	protected void doRetrieveMatchingFiles(String fullPattern, File dir, Set result) throws IOException {
     if (logger.isTraceEnabled()) {
     	logger.trace("Searching directory [" + dir.getAbsolutePath() +
     			"] for files matching pattern [" + fullPattern + "]");
     }
     for (File content : listDirectory(dir)) {
     	String currPath = StringUtils.replace(content.getAbsolutePath(), File.separator, "/");
     	if (content.isDirectory() && getPathMatcher().matchStart(fullPattern, currPath + "/")) {
     		if (!content.canRead()) {
     			if (logger.isDebugEnabled()) {
     				logger.debug("Skipping subdirectory [" + dir.getAbsolutePath() +
     						"] because the application is not allowed to read the directory");
     			}
     		}
     		else {
     			doRetrieveMatchingFiles(fullPattern, content, result);
     		}
     	}
     	if (getPathMatcher().match(fullPattern, currPath)) {
     		result.add(content);
     	}
     }
     }
    *****************************************************************
    
    1. 解析注解@Import,逻辑复杂单独整理 ConfigurationClassParser.processImports
      主要处理Import的class是否为普通类、继承ImportSelecto、DeferredImportSelector、ImportBeanDefinitionRegistrar这些类,最终将import的类生成对象放入parse的importStack属性中

    2. 解析@ImportResource,将得到的文件信息加入到configclass对象属性importedResources

    3. 解析configuration类中含有@Bean注解的方法,读取到方法加入configClass属性beanMethods中
      在读取含有@Bean注解时会在次读取一次,确认是否一致,具体的参考retrieveBeanMethodMetadata这个方法

    4. 分析configuration类的接口方法中是否含有@Bean注解方法,并加入到configclass对象属性importedResources

    5. 分析configuration的父类,如果不java基础类放入parse的knownSuperclasses属性中

  • 执行完doProcessConfigurationClass方法后将其返回的父类
    继续循环执行doProcessConfigurationClass方法,直到没有父类,并将解析过类放入parse的configurationClasses属性中

  • 处理configuration类中@Import有关逻辑,后面单独和解析注解@Import一整理
    ConfigurationClassParser.componentScanParser.process()

  • 执行parse对象的validate()方法

    1. 检查parse对象中属性configurationClasses的class是有@Configuration注解属性proxyBeanMethods是否为true,且class为final类认为异常problemReporter.error(newFinalConfigurationProblem())

    2. 检查parse对象中属性configurationClasses的class是有@Configuration注解,对有@Bean注解的方法检查是否为不可覆盖方法,若是不可覆盖产生problemReporter.error(new
      NonOverridableMethodError());

  • 生成ConfigurationClassBeanDefinitionReader类对象reader

  • 通过调用reader.loadBeanDefinitions方法,生成parse分析过的class的beandefinition并入beanfactory的beanDefinitionMap中

     	a. 判断是否需要skip,通过trackedConditionEvaluator.shouldSkip(configClass)
     	b.若class是被@Import进行的,生成beandefinition
     	c.若class中含有@注解方法,如果@Bean 注解没有设定值直接取方法名为beanname,主要是通过调用
     	   ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod方法,细节单独整理
     	d.处理@ImportResource逻辑,主要是处理按照xml生成beandefinition, 调用XmlBeanDefinitionReader.loadBeanDefinitions(resource)方法,细节单独整理
    
  • 判断经过parse.parse()解析过的类是否有新的有@Configuration注解类,若有重复以下过程,直到没有新的@Configuration类,这个通过注解@ComponentScan的basePackges可能扫到多个Configuration类

if (registry.getBeanDefinitionCount() > candidateNames.length) {
   String[] newCandidateNames = registry.getBeanDefinitionNames();
   Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
   Set<String> alreadyParsedClasses = new HashSet<>();
   for (ConfigurationClass configurationClass : alreadyParsed) {
      alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
   }
   for (String candidateName : newCandidateNames) {
      if (!oldCandidateNames.contains(candidateName)) {
         BeanDefinition bd = registry.getBeanDefinition(candidateName);

         // 检查多出来的BeanDefinition是不是配置类,需不需要解析
         if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
               !alreadyParsedClasses.contains(bd.getBeanClassName())) {
            candidates.add(new BeanDefinitionHolder(bd, candidateName));
         }
      }
   }
   candidateNames = newCandidateNames;
}
  • 在beanfactory的singletonObjects加入parse对象importStack中的内容,beanname为IMPORT_REGISTRY_BEAN_NAME【ConfigurationClassPostProcessor…importRegistry】
  1. 在次从factory的属性中beanDefinitionNames、manualSingletonNames找出是BeanDefinitionRegistryPostProcessor类型的beanname,确认是否和2中找到是一样class,若不是执行3、4、5、6

    在这里是个扩展点可以自定义BeanDefinitionRegistryPostProcessor接口实现对bean的初始化过程进行修改,或者对beanfactory进行各操作,
    ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry
    
  2. 在次重复6的过程
    可能是为了防止在6过程中自定义实现BeanDefinitionRegistryPostProcessor的接口类

  3. 用2、6、7中找出BeanDefinitionRegistryPostProcessor实现类执行postProcessBeanFactory这个方法

    在启动阶段如果没有实现BeanDefinitionRegistryPostProcessor自定义类只ConfigurationClassPostProcessor.postProcessBeanFactory
    查找beanfactory中beandefinition中没有加载class的都只加载,主要是lite和full类及@Bean方法对应的方法

  4. 执行beanfactory.beanFactoryPostProcessors属性中实现了BeanFactoryPostProcessor接口的对象方法postProcessBeanFactory,除了实现BeanDefinitionRegistryPostProcessor接口的对象

    启动阶段没有可以执行的,因为启动阶段beanFactoryPostProcessors里没有内容

  • 从前面生成的beandefinition中找出所有实现了BeanFactoryPostProcessor接口类:

    1. 找出实现了PriorityOrdered类,排序后执行postProcessBeanFactory方法

    2. 找出实现了Ordered类,排序后执行postProcessBeanFactory方法

    3. 除了以上两种类,执行postProcessBeanFactory方法

    扩展点:
    1.可以自定义实现BeanFactoryPostProcessor接口类来对beanfactory的属性进行操作,大多情况下对beandefinition操作,
    2.如果多个BeanFactoryPostProcessor这样类,可以实现PriorityOrder、Order接口来控制顺序
    另外从代码上来看10是对9补充,可能随着版本升级加入@ComponentScan和@Configuration之后9可能有点问题

registerBeanPostProcessors逻辑

  1. 找出前面生成的所有beandefinition是BeanPostProcessor接口的实现类,包括自定义实现BeanPostProcessor接口类,且按照实现PriorityOrdered、Ordered接口、未实现PriorityOrder&Ordeded、实现MergedBeanDefinitionPostProcessor的顺序排序后放入beanfactory的beanPostProcessors属性中
  2. 在beanfactory的beanPostProcessors属性中放入ApplicationListenerDetector对象
    第2个过程其实在prepareBeanFactory()进行过一次,这样做的目的是为将事件广播的放在所有的BeanPostProcessor类之后处理

initMessageSource逻辑

初始化MessageSouce Bean,并作为singleton bean名字messageSource放入容器中
如果系统开发时需要使用国际化功能,需要在@Configuration类中通@Bean方法生成messageSource的bean,否则无法使用国际化功能,原困如下:

1.在得到国际化信息时spring需要按照以下如下代码方进行
public String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException {
   if (this.parentMessageSource != null) {
      return this.parentMessageSource.getMessage(code, args, locale);
   }
   else {
      throw new NoSuchMessageException(code, locale);
   }
}
 2.生成bean的逻辑如下,如果beanfactory没有messageSource bean,但是getInternalParentMessageSource()这个方法是没有值的  
   // Use empty MessageSource to be able to accept getMessage calls.
      DelegatingMessageSource dms = new DelegatingMessageSource();
      dms.setParentMessageSource(getInternalParentMessageSource());
      this.messageSource = dms;
      beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
      if (logger.isTraceEnabled()) {
         logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
      }
   }

initApplicationEventMulticaster逻辑

1.从beanfactory获取前beanname为applicationEventMulticaster的bean,如果beanfactory不存在生成SimpleApplicationEventMulticaster对象为
2.将1中得到的bean赋给beanfactory的属性applicationEventMulticaster
扩展点:
前面提到类ApplicationListenerDetector非常关键(调用beanfactory的addApplicationListener方法)

public Object postProcessAfterInitialization(Object bean, String beanName) {
   if (bean instanceof ApplicationListener) {
      // potentially not detected as a listener by getBeanNamesForType retrieval
      Boolean flag = this.singletonNames.get(beanName);
      if (Boolean.TRUE.equals(flag)) {
         // singleton bean (top-level or inner): register on the fly
         this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
      }
      else if (Boolean.FALSE.equals(flag)) {
         if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
            // inner bean with other scope - can't reliably process events
            logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
                  "but is not reachable for event multicasting by its containing ApplicationContext " +
                  "because it does not have singleton scope. Only top-level listener beans are allowed " +
                  "to be of non-singleton scope.");
         }
         this.singletonNames.remove(beanName);
      }
   }
   return bean;
}

他在bean初始化如查发现bean是ApplicationListener接口实现会通过beanfactory的属性applicationEventMulticaster的方法addApplicationListener让bean也可侦听事件,比如下类

@Component
public class UserService implements ApplicationListener {
   public void test() {
      System.out.println("test");
   }
   @Override
   public void onApplicationEvent(ApplicationEvent event) {
      System.out.println(this.getClass().getName()+" trigger event:"+event.getSource());
   }
}

另外我们需要准备以下类(若不准备就利用spring内部的SimpleApplicationEventMulticaster来侦听所有事件,不能客制化侦听所需的事件):

@Component(AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME)
public class MyApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
   private ArrayList<ApplicationListener>  applicationListeners=new ArrayList<ApplicationListener>();
   @Override
   public void addApplicationListener(ApplicationListener<?> listener) {
       applicationListeners.add(listener);
   }

   @Override
   public void multicastEvent(ApplicationEvent event) {
      System.out.println(this.getClass().getName()+" multicastEvent "+ event);
   }

   @Override
   public void multicastEvent(ApplicationEvent event, ResolvableType eventType) {
      System.out.println(this.getClass().getName()+" multicastEvent+ResolvableType "+ event.getSource()+" "+applicationListeners.size());
      for(ApplicationListener listener:applicationListeners){
         listener.onApplicationEvent(event);
      }
   }
}

这样的话我们向beanfactory发布事件时@Compoent类才能侦听事件,上面的addApplicationListener方法必须实现,否则实现了ApplicationListener 接口bean无法侦听到事件
applicationContext.publishEvent(new ApplicationEvent(“test event”));
当然这里的事件你可以自定义一个ApplicationEvent接口实现类,然后在MyApplicationEventMulticaster.multicastEvent方法event是否为自定义类型来侦听自已的事件

onRefresh()逻辑

这里没有用处,如果不是用于web,主要生成ResourceBundleThemeSource对象给beanfactory属性themeSource
registerListeners()逻辑

  1. 将beanfactory属性applicationListeners的ApplicationListener对对象放入beanfactory的applicationEventMulticaster.defaultRetriever.applicationListeners中,通过调用getApplicationEventMulticaster().addApplicationListener(listener)方来实现,如果beanfactory中的APPLICATION_EVENT_MULTICASTER_BEAN_NAME是AbstractApplicationEventMulticaster子类,得确认是否覆盖此方法,确认listener如何放
    但是在启动阶段applicationListeners里没有数据

  2. 从beanforty里所有beandefinition里找出实现ApplicationListener类beanname放入applicationEventMulticaster.defaultRetriever.applicationListenerBeans中
    这一步其实和ApplicationListenerDetector.postProcessAfterInitialization()方法其实是重复逻辑,搞不清为什么要进行两次

finishBeanFactoryInitialization逻辑

  1. 确认beanfactory有没有conversionService bean,如有指定给beanfactory的属性conversionService
  2. 执行以下内容,功能未知,后面在分析
if (!beanFactory.hasEmbeddedValueResolver()) {
   beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
  1. 确认beandefinition中是否有LoadTimeWeaverAware接口实现类,如果进地实列化bean
  2. 将beanfactory的属性configurationFrozen变为true,意味着类解析已完成
  3. 根据所有内容beandefinition加载非lazy-init、非抽象bean,非要是通过getBean方法来实进行
    AbstractBeanFactory.getBean()逻辑较为复杂单独整理

finishRefresh逻辑

  1. 确认beanfactory有没有自定义lifecycleProcessor bean,若没有用DefaultLifecycleProcessor生成bean,并指定给beanfactory的属性lifecycleProcessor
  2. 调用lifecycleProcess 的onrefresh()方法,右启动时没定义lifecycleProcessor bean,将执行
    DefaultLifecycleProcessor.onrefresh()方法,调用beanfactory中所有实现Lifecycle接口bean的start()方法,包括lifecycleProcessor
    bean的start()方法
  3. 向beanfactory pulish事件ContextRefreshedEvent
  4. 向ManagementFactory注册beanfactory

总结

从上面整理的spring启动逻辑, invokeBeanFactoryPostProcessors至关重要,主要带有@Configuration的类比较重要,主要是得到整个系统需要生成的bean definition信息,主要是通过java的反射机制和cglib技术得到class的相关信息。

你可能感兴趣的:(JAVA开发日常问题,spring,java,servlet)