Spring ApplicationContext 初始化流程

主题

学习记录一下applicationContext在初始化过程中做的一些操作..

从全局整体来看.不会涉及太多细节.

 

applicationcontext的refresh方法是一个startup method.算是spring启动的一个方法.它处理各种配置,不管是XML还是properties还是啥.创建了各种bean.算是一个最核心的方法.

refresh方法里面包含了一大堆模板方法.每个模板都做了一些事情,相当于一个小步骤..

从代码整体来看大概包含了这么一些步骤.其中2,3,4,5,6这几部是我个人觉得最核心的步骤.我想特别记录下我的想法

 

1. prepareRefresh

 1     /**
 2      * Prepare this context for refreshing, setting its startup date and
 3      * active flag as well as performing any initialization of property sources.
 4      */
 5     protected void prepareRefresh() {
 6         this.startupDate = System.currentTimeMillis();
 7         this.active.set(true);
 8 
 9         if (logger.isInfoEnabled()) {
10             logger.info("Refreshing " + this);
11         }
12 
13         // Initialize any placeholder property sources in the context environment
14         initPropertySources();
15 
16         // Validate that all properties marked as required are resolvable
17         // see ConfigurablePropertyResolver#setRequiredProperties
18         getEnvironment().validateRequiredProperties();
19 
20         // Allow for the collection of early ApplicationEvents,
21         // to be published once the multicaster is available...
22         this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
23     }
View Code

这个方法基本啥都没做.留给子类ac去做自定义的操作.

比如web环境下的ac可能会将servletConfig或者servletContext里配置的一些参数值也当做属性值加入到spring中.因为你的spring的部分配置可能会依赖这些web.xml里的配置

另外就是对必要属性的验证.如果有必要的话可以自己去写一个ac继承spring,然后重写initPropertySources方法去设置你觉得必要的属性.然后当getEnvironment().validateRequiredProperties();

的时候如果没有找到你之前setRequiredProperties的那些属性.就会提示报错.

 

 

2. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

获取BF这个步骤主要作用就是构造一个bf.然后去加载对应的beanDifination信息.

    /**
     * Tell the subclass to refresh the internal bean factory.
     * @return the fresh BeanFactory instance
     * @see #refreshBeanFactory()
     * @see #getBeanFactory()
     */
    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        refreshBeanFactory();
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (logger.isDebugEnabled()) {
            logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
        }
        return beanFactory;
    }

getBeanFactory方法就是获取当前这个ac里设置的bf,没啥好说的.主要看看refreshBeanFactory这个方法里面做了啥.

 1     /**
 2      * This implementation performs an actual refresh of this context's underlying
 3      * bean factory, shutting down the previous bean factory (if any) and
 4      * initializing a fresh bean factory for the next phase of the context's lifecycle.
 5      */
 6     @Override
 7     protected final void refreshBeanFactory() throws BeansException {
 8         if (hasBeanFactory()) {
 9             destroyBeans();
10             closeBeanFactory();
11         }
12         try {
13             DefaultListableBeanFactory beanFactory = createBeanFactory();
14             beanFactory.setSerializationId(getId());
15             customizeBeanFactory(beanFactory);
16             // 这里不同的ac可能会有不同的loadDefination的方法,比如AnnotationConfigWebApplicationContext就会扫描注解注册BD
17             loadBeanDefinitions(beanFactory);
18             synchronized (this.beanFactoryMonitor) {
19                 this.beanFactory = beanFactory;
20             }
21         }
22         catch (IOException ex) {
23             throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
24         }
25     }
View Code

 

2.1 shuwdown之前的bf

如果当前这个ac已经有bf了(比如之前ac的refresh就调用过)了.那这里需要把这个bf shutdown.

比如把bf里的各种缓存的map情况.然后所有的单例bean如果impl了DisposableBean,还需要调用它的destroy方法去做相应的操作.

 

2.2 创建bf

DefaultListableBeanFactory beanFactory = createBeanFactory();

createBeanFactory默认返回的是DefaultListableBeanFactory类的实例.目前为止spring中还没看到其他继承这个BF的实现类.基本都是用这个类作为默认的BF.可能因为功能已经足够强大了吧..另外因为ApplicationContext也继承了BF,所以很多操作会在ac里操作掉..根据ac的不同实现做不同的操作.可能这也是bf没有这么多实现的原因吧...

 

2.3 配置bf

customizeBeanFactory(beanFactory);

这是一个模板方法.允许子类ac去实现他.对bf进行一些个性化配置.比如是否需要解决单例的循环依赖呀? 是否允许beanDifination多次定义被覆盖呀? 

bf里配置还蛮多的..不过我看源码里目前子类ac也没啥进行定制的...

 

2.4 加载bd

loadBeanDefinitions(beanFactory);

BeanFactory的作用就是读取bean的配置信息变成内存中的BeanDifination.然后在创建bean的时候根据这个bd去构造具体的bean.

不同的bean的配置方式可能各种各样.比如有XML的.Properties的.传统注解@Service@Autowired的.又或是@Configuration这种java config方式的..但是他们在内存中都是通过BeanDifination来表示的(可能是不同子类).

不同的ApplicationContext代表了不同的环境.比如适用于web环境的WebApplicationContext,也有传统单独使用spring的时候的XML里的ClassPathXmlApplicationContext等等

这些不同的ac加载bd的方式也会各有不同.所以在这个loadBeanDefinitions模板方法里就是要根据不同的ac去实现不同的加载bd的方式.

比如XML的ac就应该委托XmlBeanDefinitionReader去读取bean形式的配置.转化成BeanDifination注册到BF中.

而支持Annotation的ac就应该委托AnnotatedBeanDefinitionReader这种reader去扫描Java源码.注册相应的BD.

 

当然.注册的BD不一定就是我们代码里用到的那些bean对应的bd.也可能是一些BeanPostProcessor或者子接口的实现类.

因为比如InstantiationAwareBeanPostProcessor类似这种特殊的接口都是参与Spring的生命周期可以在一些必要的时候替换掉原始的bean.或者对bean的属性进行一些加工.

比如@Autowired这种操作就是用到特殊的bpp..AutowiredAnnotationBeanPostProcessor..同理@Configuration也是一样..

 

所以说不同的bean的配置方式在spring创建对应的bean过程中走的流程可能是不一样的,这也是Spring比较灵活的地方.

有些bean会被适用于它的bpp去处理去生成或者去注入属性.而有一些可能就是比较原生,直接通过bd被BeanWrapper给new出来.

 

 

3.prepareBeanFactory

 1     /**
 2      * Configure the factory's standard context characteristics,
 3      * such as the context's ClassLoader and post-processors.
 4      * @param beanFactory the BeanFactory to configure
 5      */
 6     protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
 7         // Tell the internal bean factory to use the context's class loader etc.
 8         beanFactory.setBeanClassLoader(getClassLoader());
 9         beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
10         beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
11 
12         // Configure the bean factory with context callbacks.
13         beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
14         beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
15         beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
16         beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
17         beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
18         beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
19 
20         // BeanFactory interface not registered as resolvable type in a plain factory.
21         // MessageSource registered (and found for autowiring) as a bean.
22         beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
23         beanFactory.registerResolvableDependency(ResourceLoader.class, this);
24         beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
25         beanFactory.registerResolvableDependency(ApplicationContext.class, this);
26 
27         // Detect a LoadTimeWeaver and prepare for weaving, if found.
28         if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
29             beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
30             // Set a temporary ClassLoader for type matching.
31             beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
32         }
33 
34         // Register default environment beans.
35         if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
36             beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
37         }
38         if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
39             beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
40         }
41         if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
42             beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
43         }
44     }

大致做的事情就是

 

3.1 SPEL

设置spelResolver用于spel的解析. spel单独就有一个自己的模块. 具体就不说了.

 

3.2 PropertyEditorRegistrar

设置PropertyEditorRegistrar. spring的配置文件很多都是XML或者property这种文本.读取出来的都是字符串.但是java对象有各种类型的属性.所以生成bean的时候需要做一些类型转化

比如 String -> Int类似这种, 就需要自己去写一个PropertyEditorSupport的实现类,去impl setAsText(String) 的方法.把XML里得到的字符串转化成Java对象里的Int值.Spring自带了很多这种Editor

 

ResourceEditorRegistrar.java

 

 

 

另外spring的类型转化也有很多种方法.这种PropertyEditorSupport(java.beans包下的)可能是早期的方案.后续的SPring版本中有一些地方转化用到了conversionService. 里面又设计到其他的一些类型转化接口.

可以参考我的这篇文章
https://www.cnblogs.com/abcwt112/p/7447435.html

 

3.3 注册BeanPostProcessor

beanPostProcessor可以在bean初始化方法(比如XML里的init-method或者InitializingBean的afterPropertySet方法)前和后对bean进行加工或者返回一个wrapper替换掉原本的bean.

注意的是bean的属性填充是在bpp2个操作之前的.就是populate(BeanFactory创建bean的一个利用BeanWrapper去设置bean的属性的时候回调用的方法)方法已经被调用过的.

Spring在这里new了一个ApplicationContextAwareProcessor

 1     @Override
 2     public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
 3         AccessControlContext acc = null;
 4 
 5         if (System.getSecurityManager() != null &&
 6                 (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
 7                         bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
 8                         bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
 9             acc = this.applicationContext.getBeanFactory().getAccessControlContext();
10         }
11 
12         if (acc != null) {
13             AccessController.doPrivileged(new PrivilegedAction<Object>() {
14                 @Override
15                 public Object run() {
16                     invokeAwareInterfaces(bean);
17                     return null;
18                 }
19             }, acc);
20         }
21         else {
22             invokeAwareInterfaces(bean);
23         }
24 
25         return bean;
26     }
27 
28     private void invokeAwareInterfaces(Object bean) {
29         if (bean instanceof Aware) {
30             if (bean instanceof EnvironmentAware) {
31                 ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
32             }
33             if (bean instanceof EmbeddedValueResolverAware) {
34                 ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(
35                         new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
36             }
37             if (bean instanceof ResourceLoaderAware) {
38                 ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
39             }
40             if (bean instanceof ApplicationEventPublisherAware) {
41                 ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
42             }
43             if (bean instanceof MessageSourceAware) {
44                 ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
45             }
46             if (bean instanceof ApplicationContextAware) {
47                 ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
48             }
49         }
50     }
View Code

对实现了一部分Aware的bean做方法调用.

比如你的bean impl了ApplicationContextAware这个接口.那就会调用你的setApplicationContext方法去让你有机会将ac设置为你的bean里的一个属性.

为什么Aware的一些接口要用这些内置的bpp去处理,而不是当做一般的bean注入?

我个人觉得是第一,要控制是什么时候注入这些bean.比如如果只是在一般的populate属性的时候注入这个ac.那这个时候不是所有的bean都被new过..可能会有一些意想不到的问题.

第二我觉得是因为ac和BeanFactory可能会有多个,比如早期没有springboot的时候.spring会有一个ac.然后springmvc自己也会有一个ac.有parent和child的关系.那你在一个bean里注入ac.就会有2个符合条件的ac选择.这也是有问题的.

 

3.4 忽略部分类型bean的注入

1         beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
2         beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
3         beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
4         beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
5         beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
View Code

为什么这些类型的bean不需要注入? 因为3.3里已经在bpp里处理了

 

3.5 指定部分类型的bean注入

1         beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
2         beanFactory.registerResolvableDependency(ResourceLoader.class, this);
3         beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
4         beanFactory.registerResolvableDependency(ApplicationContext.class, this);
View Code

指定了一些bean的类型使用特定的bean注入..比如BeanFactory就使用当前这个ac对应的bf去注入即可.

 

3.6 额外注册一些Bean

 1         // Detect a LoadTimeWeaver and prepare for weaving, if found.
 2         if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
 3             beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
 4             // Set a temporary ClassLoader for type matching.
 5             beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
 6         }
 7 
 8         // Register default environment beans.
 9         if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
10             beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
11         }
12         if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
13             beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
14         }
15         if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
16             beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
17         }
View Code

如果有一些bean你没配置.那就会使用spring默认的配置.比如environment.你如果配置了.那就用你的bean

 

4. postProcessBeanFactory(beanFactory);

这个方法是一个模板方法,允许子类对bf做一些处理.

比如一些web相关的ac会在这里add一些bpp比如ServletContextAwareProcessor来对servlet做一些处理

或者在这里也可以get BF以后去调用方法增加一些BeanFactoryPostProcessor.

 

5.invokeBeanFactoryPostProcessors(beanFactory);

做到这个方法的时候BF已经加载完所有的BeanDifination了(详见第2节).但是任何bean都还没有被初始化(new).

看方法名字就知道这个方法是去激活调用beanFactoryPostProcessors的相关方法的.

beanFactoryPostProcessors这个接口还有一个子接口叫做BeanDefinitionRegistryPostProcessor.

这个子接口的postProcessBeanDefinitionRegistry方法是处理BeanDefinitionRegistry用的.可能是个新增的接口.因为我看到网上很多博客上都只写了BFPP而没有写这个接口..(因为大部分文章介绍的是早期的spring)

这个接口的会先于BFPP的postProcessBeanFactory掉用,他可以处理BeanDefinitionRegistry,有一些BF实现了这个接口,也有一些BF没有.绝大部分大部分ac使用的DefaultListableBeanFactory

是实现了这个接口的.所以可以处理BeanDefinitionRegistryPostProcessor.

 

BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry作用是给你一个机会去手动注册beanDifination..可以用这个接口去注册一些BeanFactoryPostProcessor..当然普通的BD也可以去注册或者修改.但是如果是这种目的的话最好可以使用BeanFactoryPostProcessor的postProcessBeanFactory.这样通用性更好.也更合理.

 

BeanFactoryPostProcessor的postProcessBeanFactory用于修改BeanFactory或者去修改BF里的BeanDifination..

一个典型的案例就是在早期版本的spring(还没用springboot的时候)我们会配置placeholderconfigurer.这个类就是实现了BeanFactoryPostProcessor接口.他会扫描所有bean里的属性.去把${}这种占位符替换成property文件里指定的值.常用于db的配置独立放在.properties文件中,datasource的配置放在bean.XML文件中. 

 

所以invokeBeanFactoryPostProcessors(beanFactory);这个方法所做的事情就是.

1.获取所有手动注册的BeanDefinitionRegistryPostProcessor.去调用postProcessBeanDefinitionRegistry.

所谓的手动注册就是在之前几节的模板方法中直接调用ApplicationContext的addBeanFactoryPostProcessor方法注册的BeanDefinitionRegistryPostProcessor

 

2.然后获取扫描bf中所有注册的BeanDefinitionRegistryPostProcessor.

按PriorityOrdered > Ordered > rest 去排序,依次调用postProcessBeanDefinitionRegistry方法

也就是说你的非手动注册的BeanDefinitionRegistryPostProcessor如果实现了PriorityOrdered接口.那肯定会比实现了Ordered接口的BeanDefinitionRegistryPostProcessor早调用.

同样接口的.就按接口内定义的顺序排序.比如Ordered接口.就是数字越小排在越前面

 

3.处理一般的BeanFactoryPostProcessor的postProcessBeanFactory方法.

顺序和BeanDefinitionRegistryPostProcessor一样,也是 手动注册的> PriorityOrdered > Ordered > rest

 

  1 public static void invokeBeanFactoryPostProcessors(
  2             ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
  3 
  4         // Invoke BeanDefinitionRegistryPostProcessors first, if any.
  5         Set<String> processedBeans = new HashSet<String>();
  6 
  7         if (beanFactory instanceof BeanDefinitionRegistry) {
  8             BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
  9             List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
 10             List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
 11                     new LinkedList<BeanDefinitionRegistryPostProcessor>();
 12 
 13             for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
 14                 // 特殊的BeanDefinitionRegistryPostProcessor的,比如处理@configuration.注册bd
 15                 if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
 16                     BeanDefinitionRegistryPostProcessor registryPostProcessor =
 17                             (BeanDefinitionRegistryPostProcessor) postProcessor;
 18                     registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
 19                     registryPostProcessors.add(registryPostProcessor);
 20                 }
 21                 else {
 22                     regularPostProcessors.add(postProcessor);
 23                 }
 24             }
 25 
 26             // Do not initialize FactoryBeans here: We need to leave all regular beans
 27             // uninitialized to let the bean factory post-processors apply to them!
 28             // Separate between BeanDefinitionRegistryPostProcessors that implement
 29             // PriorityOrdered, Ordered, and the rest.
 30             String[] postProcessorNames =
 31                     beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
 32 
 33             // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
 34             List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
 35             for (String ppName : postProcessorNames) {
 36                 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
 37                     priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
 38                     processedBeans.add(ppName);
 39                 }
 40             }
 41             sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
 42             registryPostProcessors.addAll(priorityOrderedPostProcessors);
 43             invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
 44 
 45             // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
 46             postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
 47             List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
 48             for (String ppName : postProcessorNames) {
 49                 if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
 50                     orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
 51                     processedBeans.add(ppName);
 52                 }
 53             }
 54             sortPostProcessors(beanFactory, orderedPostProcessors);
 55             registryPostProcessors.addAll(orderedPostProcessors);
 56             invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
 57 
 58             // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
 59             boolean reiterate = true;
 60             while (reiterate) {
 61                 reiterate = false;
 62                 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
 63                 for (String ppName : postProcessorNames) {
 64                     if (!processedBeans.contains(ppName)) {
 65                         BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
 66                         registryPostProcessors.add(pp);
 67                         processedBeans.add(ppName);
 68                         pp.postProcessBeanDefinitionRegistry(registry);
 69                         reiterate = true;
 70                     }
 71                 }
 72             }
 73 
 74             // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
 75             invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
 76             invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
 77         }
 78 
 79         else {
 80             // Invoke factory processors registered with the context instance.
 81             invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
 82         }
 83 
 84         // Do not initialize FactoryBeans here: We need to leave all regular beans
 85         // uninitialized to let the bean factory post-processors apply to them!
 86         String[] postProcessorNames =
 87                 beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
 88 
 89         // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
 90         // Ordered, and the rest.
 91         List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
 92         List<String> orderedPostProcessorNames = new ArrayList<String>();
 93         List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
 94         for (String ppName : postProcessorNames) {
 95             if (processedBeans.contains(ppName)) {
 96                 // skip - already processed in first phase above
 97             }
 98             else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
 99                 priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
100             }
101             else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
102                 orderedPostProcessorNames.add(ppName);
103             }
104             else {
105                 nonOrderedPostProcessorNames.add(ppName);
106             }
107         }
108 
109         // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
110         sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
111         invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
112 
113         // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
114         List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
115         for (String postProcessorName : orderedPostProcessorNames) {
116             orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
117         }
118         sortPostProcessors(beanFactory, orderedPostProcessors);
119         invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
120 
121         // Finally, invoke all other BeanFactoryPostProcessors.
122         List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
123         for (String postProcessorName : nonOrderedPostProcessorNames) {
124             nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
125         }
126         invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
127     }
View Code

 

 

6.registerBeanPostProcessors(beanFactory);

注册BPP.

之前是BFPP用于处理BeanFactory,处理其中的BeanDifination.那这里就是注册BPP用于在处理bean了.

对于BPP并没有手动注册的方法..比如ac的addBeanPostProcessor这种方法..BFPP相关方法的调用是先于bean 初始化(new)的,很好理解,因为是对BeanFactory的处理,而不是当bean的处理.. (但是BFPP也是会在bean new之前全部被扫描从bf里找出来特殊处理...所以从这点上说好像不用手动配置也可以..)

而bpp是在bean 初始化或者填充属性过程中处理的.是在bean被new的过程中处理的...没必要手动注册...因为当前这一步仅仅是添加bpp..还不会调用bpp的相关方法(因为这个时候还没有new bean)...这一点BFPP不同(BFPP直接调用相关方法).直接和一般的bean一样配置就行了.

 

BPP的处理顺序和BFPP一样(再次强调一下,这里只是把这些BPP的特殊的bean new出来了.并不会new 一般的bean.所以这里不会调用BPP的相关方法).最后就是BPP也有特殊的子接口,叫做MergedBeanDefinitionPostProcessor,是最后处理的.所以这些MergedBeanDefinitionPostProcessor会在BPP的最内层.(如果只是当做一般的BPP去使用相关方法的话就不要使用这个子接口.因为会影响处理的顺序..)

 

7.initMessageSource

初始化MessageSource,主要用于国际化.没怎么用过.没深入研究..大致是读取不同语言的properties根据Locale去做相应的处理.

 

8.initApplicationEventMulticaster

同7个人没咋用过.

ApplicationContext可以publish一些Event.你也可以注册一些Listener去监听自己感兴趣的实践.

 

9.onRefresh();

也是一个模板方法.给子类ac一个机会去初始化自己想要初始化的特殊的bean

比如一些web的ac会初始化ThemeSource...用于web页面的主题展示和切换...比如jsp里的标签:<spring:theme code="style"/>

现在前后端分离了这个感觉很少用了...

 

10.registerListeners();

配合8.可以注册一些listener去监听你感兴趣的ApplicationEvent

 

11.finishBeanFactoryInitialization(beanFactory);

除了注册一些特殊的bean.比如ConversionService以外.

最重要的就是对于之前BF加载的每一个BD.如果这个bean是单例并且不是lazy的.不是abstract的(XML里可以配置一个bean是abstract.用于继承简化配置),就去初始化对应的bean.也就是通过BeanFactory.doGetBean方法去创建这个bean的实例..

里面涉及比较复杂的步骤...涉及各种BPP的调用,还有各种情况的处理...比如循环依赖, 代理方法什么的.....后面会再分享..

 

12.finishRefresh()

完成refresh.个人没怎么用过.

会注册LifecycleProcessor.如果你的bean实现了Lifecycle接口.在ac做stop.refresh或者start等方法的时候你的bean也会被调用这些方法给你一些回调处理的机会.

 

 

 

 

 

posted @ 2020-03-01 12:09  abcwt112  阅读(2956)  评论(0编辑  收藏  举报