Spring ApplicationContext 初始化流程

主题

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

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

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

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


// BF忽略Aware接口,用自己的BPP来注入这些对象
// 指定特殊autowired对象
// 注入特殊的bean,systemProps,env等

猜你喜欢

转载自www.cnblogs.com/abcwt112/p/12388982.html