说明:
SpringIoC的源代码很深,其最精华的部分位于AbstractApplicationContext->refresh()方法中,当然即使是这样,这里也只分析了其精华中的精华
第一步 createApplicationContext():初始化IoC容器
在DefaultResourceLoader中会初始化以下三个属性:
// 类加载器Launcher$AppClassLoader
private ClassLoader classLoader;
// 协议解析器容器
private final Set<ProtocolResolver> protocolResolvers = new LinkedHashSet<>(4);
// 配置文件缓存器
private final Map<Class<?>, Map<Resource, ?>> resourceCaches = new ConcurrentHashMap<>(4);
在AbstractApplicationContext类中主要初始化:
// 确定日志类型,比如log4j,logback
protected final Log logger = LogFactory.getLog(getClass());
// 创建beanFactory后置处理器
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
// 创建事件监听器容器
private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
/*resourceLoader:AnnotationConfigApplicationContext
* pathMatcher: AntPathMatcher ant风格的解析器
*/
private ResourcePatternResolver resourcePatternResolver;
在GenericApplicationContext中创建Spring IoC最重要的对象beanFactory。
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
最后才会调用AnnotationConfigServletWebServerApplicationContext()的构造函数完成Spring容器的创建和初始化工作。
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
在执行reader变量初始化的时候,会添加5个beanDefinitionMap,如下:
// 配置类处理器,也是第一次找bean所用到的后置处理器
1.org.springframework.context.annotation.internalConfigurationAnnotationProcessor
// 自动注入类处理器
2.org.springframework.context.annotation.internalAutowiredAnnotationProcessor
// 通用注解类处理器
3.org.springframework.context.annotation.internalCommonAnnotationProcessor
4.org.springframework.context.event.internalEventListenerProcessor
5.org.springframework.context.event.internalEventListenerFactory
第二步 load(context, sources.toArray(new Object[0])):注册启动类bd
解析启动类,并将主源添加至beanDefinitionMap,如果有多个则按照顺序添加
第三步 刷新容器
第一步 prepareRefresh():初始化容器
第二步 obtainFreshBeanFactory():获得IOC容器
第三步 容器准备
prepareBeanFactory(beanFactory):准备化工作,添加两个beanPostProcessors,注册默认的环境bean。
postProcessBeanFactory(beanFactory):作用域新增request和session
第四步 invokeBeanFactoryPostProcessors(beanFactory)
- 找到当前IoC容器中实现
BeanDefinitionRegistryPostProcessor的后置处理器并实例化,调用各后置处理器的postProcessBeanDefinitionRegistry(registry)方法,找bean,添加到bdMap和bdNames中参考1 参考2 - 再一次查找当前IoC容器中实现
BeanDefinitionRegistryPostProcessor的后置处理器并实例化,未调用过的调用各后置处理器的postProcessBeanDefinitionRegistry(registry)方法,找bean,添加到bdMap和bdNames中 - 调用各后置处理器的
postProcessBeanFactory(beanFactory)方法,其中ConfigurationClassPostProcessor对@Configuration做Cglib增强 - 找到当前IoC容器中实现
BeanFactoryPostProcessor的后置处理器并实例化,未调用过的调用各后置处理器的postProcessBeanFactory(beanFactory)方法
第五步 registerBeanPostProcessors(beanFactory):注册后置处理器
查找当前IoC容器中实现BeanPostProcessor的后置处理器,确保都添加到beanPostProcessors集合中,并且都实例化,确保beanPostProcessors有BeanPostProcessorChecker和ApplicationListenerDetector这两个后置处理器。后面实例化用到的后置处理器就是这些了。
不同的后置处理器有不同的作用,举最常见的几个后置处理器说明:
ApplicationListenerDetector(有用到,已见过)
与监听器有关,通过postProcessAfterInitialization方法,当前bean如果实现了ApplicationListener接口,放入应用上下文的的applicationListeners和applicationEventMulticaster中,如定时任务后置处理器ScheduledAnnotationBeanPostProcessor。
AutowiredAnnotationBeanPostProcessor(有用到,已见过)
是Spring实现依赖注入和依赖查找的核心技术。它在bean实例化过程中,通过findAutowiredAnnotation方法寻找beanClass中是否有@Autowird, @Value注解。上述注解的依赖注入就是通过这个后置处理器实现的。
CommonAnnotationBeanPostProcessor(有用到,已见过)
Spring的通用注解后置处理器,专门用来处理@PostConstruct,@PreDestroy, @Resource。上述注解的依赖注入和方法的执行就是通过这个后置处理器实现的。
AnnotationAwareAspectJAutoProxyCreator(有用到,已见过)
与AoP的实现有关。
ConfigurationPropertiesBindingPostProcessor(有用到,已见过)
用于解析@ConfigurationProperties注解,并将配置文件中的内容绑定到对应的bean的对象上。
大致过程为:
- 取Bean的所有字段,遍历,这时会将字段名由驼峰改为中划线,如testAge变成test-age
- 遍历属性源,找到名称为test-age的属性值
- 如果没有的话,遍历属性源中的所有key,依次与test-age比较,相似则取其属性值(无视大小写与特殊字符,如testAge、TEST_AGE都认为相似)
- 找到的话利用反射赋值,否则跳过
@ConfigurationProperties与@Value最大的区别是前者没有对应属性跳过,后者没有对应属性直接报错
PostProcessorRegistrationDelegate$BeanPostProcessorChecker
BeanPostProcessorChecker是PostProcessorRegistrationDelegate的内部类。BeanPostProcessorChecker的官方注释如下:当bean在BeanPostProcessor实例化期间创建时,即当bean不符合所有BeanPostProcessor处理的条件时,记录信息消息的BeanPostProcessor。值得说明的是,它只针对于Spring不对外公开的“基础设施”类提供检查。(bd. role=ROLE_INFRASTRUCTURE)。
ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor
用于BeanFactoryAware接口的bean的增强处理。
ApplicationContextAwareProcessor(有用到,已见过)
ApplicationContextAwareProcessor负责EnvironmentAware、ResourceLoaderAware、ApplicationContextAware等的注入,当beanClass实现ApplicationContextAware接口的时候,会执行setApplicationContext方法;当beanClass实现EnvironmentAware接口的时候,会执行setEnvironment方法。
很典型的一个是当beanName为dispatcherServlet时,会将应用上下文的环境赋给它的environment成员变量,将应用上下文赋给它的webApplicationContext变量。
通过实现aware接口的形式得到应用上下文,然后得到指定的bean就是利用这个后置处理器实现的。
第六步 实例化前准备
initMessageSource():初始化上下文中的消息源
initApplicationEventMulticaster():初始化上下文中的监听器管理对象。如果IoC容器有名称为applicationEventMulticaster的bean,直接用它;否则实例化SimpleApplicationEventMulticaster对象,取上述名称,并注入到IoC容器中
onRefresh():创建web服务器、启动、Servlet类、过滤器,详细见Tomcat的实例化与启动
registerListeners():将上下文中的监听器转给它的成员变量applicationEventMulticaster的成员变量defaultRetriever的applicationListeners中
第七步 finishBeanFactoryInitialization(beanFactory)
实例化bean,这里实际实例化的是非后置处理器,且为单例、非懒加载的bean
具体实例化的的流程见此
第八步 finishRefresh()
生命周期处理器、发布相应的的事件、web服务开启监听
详情可见Tomcat的监听与销毁中的相关部分