前言
如果你之前一直在使用 Spring、Spring MVC 框架,那么一定需要编写大量的 xml 配置文件。如今,Spring Boot、Spring Cloud 兴起之后,其底层都是基于 Spring 注解驱动,使用大量的注解替代原先的 xml 配置文件,通过学习 Spring 注解驱动开发,了解每个注解的基本使用以及背后的原理,便于以后我们深入学习与使用 Spring Boot、Spring Cloud 框架。
前期准备工作
创建项目
next→next→finish→项目创建成功。
引入依赖
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.25.RELEASE</version>
</dependency>
成功引入依赖:
容器
概述
Spring 之所以被广泛使用,是因为对于开发大型项目及其方便简单,这一切离不开 Spring 容器帮助我们管理 bean 的生命周期,那么 Spring 容器到底是什么呢?
bean 是 Spring 的的核心组成,而 Spring 容器就是用于管理这些对象的生命周期,例如:创建、销毁等。
项目中我们通过 ApplicationContext 的实现类来获取上下文,获取容器中的 bean 的元数据。
从代码上讲:一个 Spring 容器就是某个实现了 ApplicationContext 接口的类的实例。也就是说,从代码层面,Spring 容器其实就是一个 ApplicationContext(一个实例化对象)。
从源码角度来说,Spring 容器就是实现了 ApplicationContext 类的实例,获取当前环境的实例即可获取容器的内容,不同的项目环境上下文的实现类不同。
如:
# 实现 AbstractApplicationContext,xml 和注解都可以初始化
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry
# Spring Boot 中提供的实现,需要 Web Server 环境下使用
public class AnnotationConfigReactiveWebServerApplicationContext extends ReactiveWebServerApplicationContext implements AnnotationConfigRegistry
容器的功能
容器的分类及特点
容器的运行原理
创建方式
//创建基于注解的 springIOC 容器
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);
//创建基于配置文件的 springIOC 容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-app.xml");
// 创建基于注解的 WebServer 环境的 springIOC 容器,等等。。。。。。。。。。。。。。。。
ApplicationContext applicationContext = new AnnotationConfigServletWebServerApplicationContext();
运行原理
本文以 AnnotationConfigApplicationContext 为例,AnnotationConfigApplicationContext 构造器源码,用于初始化容器。
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//1.会首先调用父类 GenericApplicationContext 中的构造方法,初始化工厂 bean 为 new DefaultListableBeanFactory()
//2.调用自己的构造方法,初始化了一个读取器:AnnotatedBeanDefinitionReader reader;一个扫描器:ClassPathBeanDefinitionScanner scanner
//3.在 reader 的初始化构造方法中,还注册了 6 个 post processors
this();
//注册 bean,注册就是把 bean 都放在某个地方,一个并发 map 中,Map<String, BeanDefinition> beanDefinitionMap
//这调用了 AnnotatedBeanDefinitionReader reader 的注册方法
//只注册了 6 个 post process 类
register(annotatedClasses);
//实现的 bean 的初始化;
//自定义的 bean 也在这里注册并初始化
refresh();
}
1. 注册容器 register()
源码解析:
public void register(Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
this.reader.register(annotatedClasses);
}
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
//得到 bean 的描述信息,比如 bean 的注解,作用范围,是否懒加载,注入方式等
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
//被条件注解@Conditional 注释的 bean 跳过注册
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(instanceSupplier);
//解析 bean 的 Scope,比如是否单例 singleton 还是其他
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
//生成 bean name,默认就是类名小写
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//通过判断注解内容,设置一些公共属性,比如是否懒加载,优先级等
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
} else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
} else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
register 主要分为三步(只要是注册 BeanDefinition,都是这 3 步):
- 根据 class 文件获取 BeanDefinition,这里是其实现类 AnnotatedGenericBeanDefinition abd;
- 将 BeanDefinition 放到 BeanDefinitionHolder 中进一步封装;
- 最后一行,执行注册动作。
测试
随便一个普通的 Java 类进行注册到容器中:
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(FistBeanFactoryPostProcessor.class);
context.refresh();
FistBeanFactoryPostProcessor postProcessor = (FistBeanFactoryPostProcessor) context.getBean("fistBeanFactoryPostProcessor");
System.out.println(null != postProcessor);
}
通过断点调试,省略中间其它过程说明,直接上核心代码:
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
// 所有的 bean 注册最终都是 put beanDefinitionMap 中
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
// 注册的 bean name
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
2. 刷新容器 refresh()
AbstractApplicationContext 是 ApplicationContextspring IOC 容器的基类,refresh 方法是 Spring 最核心的方法,搞清楚这个方法的运行过程,拓展原理基本一看就会。
Spring 容器创建之后,会调用它的 refresh 方法刷新 Spring 应用的上下文。
Spring Boot 项目启动 run 中也是调用 refresh() 刷新上下文:
源码解析:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
//前期准备;记录了容器启动时间;容器状态;刷新一些在此方法之前就可能已经存在的监听器
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//最终得到 DefaultListableBeanFactory,也就是在 this()方法中通过父类构造函数初始化的那个 bean factory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//准备 bean factory,初始化工厂的一些标准固定的容器特性
//因为后边一系列容器初始化操作,都是基于 beanFactory,所以前期准备得充足
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
//空方法,用于子类扩展功能
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//实例化并执行之前已经注册了的各种 BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//实例化 拦截 bean 创建的处理器 BeanPostProcessor;
//这里的注册,是指把实例化的 BeanPostProcessor 存到 beanFactory 的某个 list 中
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
//初始化容器的 MessageSource 类型的 bean,MessageSource 用于解析消息
initMessageSource();
// Initialize event multicaster for this context.
//初始化容器的事件广播
//用于管理若干 ApplicationListener 对象,并向他们推送消息
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
//空方法,在特定的子类中 初始化其他特殊 bean
onRefresh();
// Check for listener beans and register them.
//注册实现了 ApplicationListener 接口的监听者
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//实例化剩下的单例 bean,完成全部 bean 的实例化,除了懒加载的
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
//最后一步,完成此刷新方法,发布完成事件
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
内部方法解析
总共分为 12 个重要过程,这里挑选重点解析。
1. prepareRefresh
protected void prepareRefresh() {
// Switch to active.
//容器启动时刻
this.startupDate = System.currentTimeMillis();
//容器激活状态,默认没有关闭
this.closed.set(false);
//容器激活状态,默认激活的
this.active.set(true);
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// Initialize any placeholder property sources in the context environment.
//空方法
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
//执行 refresh 之前就已经注册的 listeners 集合,如果没有,就初始化集合;
//调试发现是 null 的
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
//如果不为空,重新设置到 applicationListeners 监听器集合
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
//事件集合初始化
this.earlyApplicationEvents = new LinkedHashSet<>();
}
2. invokeBeanFactoryPostProcessors(beanFactory)
实例化并执行之前已经注册了的各种 BeanFactoryPostProcessor,可用于拓展。
BeanFactoryPostProcessor 是 beanFactory 的后置处理器,也就是说当所有的 bean 定义已经保存并加载到 beanFactory,但是却没有被实例化。那么执行顺序:beanFactory > BeanFactoryPostProcessor > bean , 也就是说初始化完 beanFactory 之后 BeanFactoryPostProcessor 才会被调用,因此 BeanFactoryPostProcessor 是在 bean 初始化之后才会被调用,使用场景:用于定制或者修改 BeanFactory 的内容。
BeanFactoryPostProcessor 原理如下。
1. IOC 容器创建对象:
invokeBeanFactoryPostProcessors(beanFactory);
2. 先根据类型获取各种 postProcessorNames:
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
分类保存为各种 priorityOrderedPostProcessors、orderedPostProcessors、nonOrderedPostProcessors 的集合其实就是各种 BeanFactoryPostProcessor。
然后分别排序上一步的各种集合,按顺序分别执行各种 BeanFactory 的后置处理器。
案例:实现 BeanFactoryPostProcessor 接口。
public interface BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for overriding or adding
* properties even to eager-initializing beans.
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
public class FistBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
int beanDefinitionCount = beanFactory.getBeanDefinitionCount();
System.out.println("容器中的 bean 数量:" + beanDefinitionCount);
int beanPostProcessorCount = beanFactory.getBeanDefinitionCount();
System.out.println("beanPostProcessorCount:" + beanPostProcessorCount);
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
for (String beanName : beanDefinitionNames) {
System.out.println("beanDefinitionName:" + beanName);
}
System.out.println("--------------------------BeanFactoryPostProcessor is after----------------------------------");
}
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(FistBeanFactoryPostProcessor.class);
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String beanName : beanDefinitionNames) {
System.out.println("beanName:" + beanName);
}
}
}
输出结果:
3. postProcessBeanFactory(beanFactory)
空方法,用于子类扩展功能。
4. BeanDefinitionRegistryPostProcessor
- 在所有 bean 定义信息将要被加载,bean 实例还未创建的;
- 优先于 BeanFactoryPostProcessor 执行;
- 利用 BeanDefinitionRegistryPostProcessor 给容器中再额外添加一些组件。
5. BeanFactoryPostProcessor 原理
IOC 创建对象
refresh() -> invokeBeanFactoryPostProcessors(beanFactory);
从容器中获取到所有的 BeanDefinitionRegistryPostProcessor 组件。
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class ..);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry) -> 依次触发所有的 postProcessBeanDefinitionRegistry() 方法 。
再来触发 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory) -> postProcessBeanFactory() 方法 BeanFactoryPostProcessor。
之后从容器中找到 BeanFactoryPostProcessor 组件,然后依次触发 postProcessBeanFactory() 方法。
案例:
public class FistBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
System.out.println("FistBeanDefinitionRegistryPostProcessor...bean 的数量:"+beanDefinitionRegistry.getBeanDefinitionCount());
RootBeanDefinition definition = new RootBeanDefinition(FistBeanFactoryPostProcessor.class);
beanDefinitionRegistry.registerBeanDefinition("test",definition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("FistBeanDefinitionRegistryPostProcessor...bean 的数量:"+configurableListableBeanFactory.getBeanDefinitionCount());
}
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(FistBeanDefinitionRegistryPostProcessor.class);
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String beanName : beanDefinitionNames) {
System.out.println("beanName:" + beanName);
}
}
}
6. registerListeners()
用于管理 ApplicationListener:
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
//广播事件到对应的监听器;
//earlyApplicationEvents 是在第一个方法 prepareRefresh()中初始化的
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
7. finishBeanFactoryInitialization(beanFactory)
实例化所有的 bean,除了懒加载的 bean。
8. finishRefresh()
发布所有的事件:
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
//执行 LifecycleProcessor 的方法
getLifecycleProcessor().onRefresh();
// Publish the final event.
//发布完成事件给所有的监听者
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
总结
源码执行过程详解
prepareRefresh 准备刷新容器
- initPropertySources() 自定义属性设置,空方法,留给子类继承。
- getEnvironment.validateRequiredProperties 首先获取环境配置,然后校验必需属性。
- this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); 初始化事件监听器。
- this.earlyApplicationEvents = new LinkedHashSet<>(); 初始化早期事件。
obtainFreshBeanFactory 获取组件工厂
- refreshBeanFactory 新建一个组件工厂,类型为 DefaultListableBeanFactory,然后对这个组件工厂设置了一个序列化 ID。
- getBeanFactory 返回刚刚创建的组件工厂。
prepareBeanFactory 对组件工厂做各种预处理设置
- 在组件工厂中设置类加载器、属性解析器等。
- 在组件工厂中添加部分组件后置处理器,例如 ApplicationContextAwareProcessor、ApplicationListenerDetector。
- 在组件工厂中设置忽略自动注入的接口。
- 设置自动装配规则。
- 在组件工厂中注册一些组件,例如环境配置 ConfigurableEnvironment。
postProcessBeanFactory 组件工厂的后置处理工作
invokeBeanFactoryPostProcessors 执行组件工厂后置处理器
这一步是在组件工厂的标准初始化(1~4)之后进行的,主要是执行 BeanFactoryPostProcessor 及其子接口的。
BeanFactoryPostProcessor 的子接口主要是指 BeanDefinitionRegistryPostProcessor,可以向容器中注册新的组件,这个接口的特点是有两个方法,一个是自身的 postProcessBeanDefinitionRegistry,另一个继承自 BeanFactoryPostProcessor 的 postProcessBeanFactory,从源码可以看出,Spring 会先执行 BeanDefinitionRegistryPostProcessor 类型的组件的自身方法,然后执行其继承方法,最后才调用非 BeanDefinitionRegistryPostProcessor 的 BeanFactoryPostProcessor 的后置处理方法。
- 从容器器中获取 BeanDefinitionRegistryPostProcessor 类型的组件。
- 将 BeanDefinitionRegistryPostProcessor 类型的组件按照顺序分类并排序,即是否实现了 PriorityOrdered、Ordered 接口。
- 依次执行实现了 PriorityOrdered 接口的、实现了 Ordered 接口的、没有实现任何顺序接口的组件的 postProcessBeanDefinitionRegistry 方法。
- 执行所有 BeanDefinitionRegistryPostProcessor 组件的 postProcessBeanFactory 方法。
- 从容器中获取其他的 BeanFactoryPostProcessor 类型的组件,即不是 BeanDefinitionRegistryPostProcessor 类型的。
- 剩下的步骤跟上面类似,就是先按照实现的顺序接口分类,在每个类别下排序,然后依次执行它们的 postProcessBeanFactory 方法。
registerBeanPostProcessors 注册组件后置处理器
这种处理器用于拦截 bean 的创建过程。beanPostProcessor 有很多子接口,每种子接口的执行时机各有不同。
- DestructionAwareBeanPostProcessor
- InstantiationAwareBeanPostProcessor
- MergedBeanDefinitionPostProcessor
- SmartInstantiationAwareBeanPostProcessor
1. 获取所有的 beanPostProcessor 的组件名。
2. 将所有的组件按优先顺序分为三类:
- 实现了 PriorityOrdered 接口的列表 priorityOrderedPostProcessors
- 实现了 Ordered 接口的列表 orderedPostProcessors
- 没有实现任何顺序接口的列表 nonOrderedPostProcessors
还有一种特殊情况,凡是 MergedBeanDefinitionPostProcessor 类型的,都放在 internalPostProcessors 中。
3. 注册 priorityOrderedPostProcessors。
4. 注册 orderedPostProcessors。
5. 注册 nonOrderedPostProcessors。
6. 注册 internalPostProcessors。
7. 注册 ApplicationListenerDetector,它的作用是在组件初始化之后判断其是否为 ApplicationListner 类型,如果是,则将其添加进容器的监听器集合。
initMessageSource 初始化消息源组件
用于消息绑定、消息解析等功能,并且提供国际化解决方案。
- 获取 beanFactory。
- 判断 beanFactory 中是否包含 id 为 messageSource 的组件。
- 如果已存在,则赋值给容器的 messageSource 属性,这种情况是我们自己在容器中注册了这个组件。
- 如果不存在,则新建一个 DelegatingMessageSource,并赋值给容器的 messageSource 属性,然后在 beanFactory 中注册这个新组件,并设置其 id 为 messageSource。
initApplicationEventMulticaster 初始化事件广播器
- 获取 beanFactory。
- 判断 beanFactory 中是否存在 id 为 applicationEventMulticaster 的组件
- 如果已存在,则赋值给容器的 applicationEventMulticaster 属性,这种情况是我们自己在容器中注册了这个组件。
- 如果不存在,则新建一个 SimpleApplicationEventMulticaster,并赋值给容器的 applicationEventMulticaster 属性,然后在 beanFactory 中注册这个新组件, 并设置其 id 为 applicationEventMulticaster。
onRefresh
留给子类继承的,我们可以自定义子容器,在重写方法中做一些我们想要的操作。
registerListeners 注册事件监听器
- 获取容器的属性 applicationListeners,这是一个事件监听器的集合,将集合中的每个元素都添加进事件广播器 getApplicationEventMulticaster().addApplicationListener(listener);。
- 从容器中获取所有 ApplicationListener 类型的组件,将这些组件添加进事件广播器。
- 派发之前步骤产生的事件。
finishBeanFactoryInitialization 完成剩下的单实例 bean 的初始化
- 进入 DefaultListableBeanFactory.preInstantiateSingletons 方法,获取容器中所有的组件 id 列表。
- 获取容器中的所有 Bean,依次进行初始化和创建对象。
- Bean 不是抽象的,是单实例的,是非懒加载。
判断是否是 FactoryBean;是否是实现 FactoryBean 接口的 Bean;如果是就用工厂 bean 来创建及 FacBean 中的 getObject 同 SpringIOC 中的二(3)。如果不是工厂 Bean。利用 getBean(beanName) 创建对象。
getBean(beanName);
ioc.getBean();
AbstractBeanFactory.doGetBean(name, null, null, false);
先获取缓存中保存的单实例 Bean。如果能获取到说明这个 Bean 之前被创建过(所有创建过的单实例 Bean 都会被缓存起来),Object sharedInstance = getSingleton(beanName); 缓存到 DefaultSingletonBeanRegistry 类的 singletonObjects 单例对象存储的 Map 一级缓存。
缓存中获取不到,开始 Bean 的创建对象流程。标记当前 bean 已经被创建:
markBeanAsCreated(beanName);
获取 Bean 的定义信息:
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName)
获取当前 Bean 依赖的其他 Bean,如果有按照 getBean(dep) 把依赖的 Bean 先创建出来:
String[] dependsOn = mbd.getDependsOn()
启动单实例 Bean 的创建流程如下:
AbstractAutowireCapableBeanFactory.createBean(beanName, mbd, args);
让 BeanPostProcessor 先拦截返回代理对象:
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
InstantiationAwareBeanPostProcessor 提前执行,先触发 postProcessBeforeInstantiation(),如果有返回值,触发 postProcessAfterInitialization()。
如果前面的 InstantiationAwareBeanPostProcessor 没有返回代理对象,调用 AbstractAutowireCapableBeanFactory.doCreateBean 创建 Bean。
创建 Bean 实例:
createBeanInstance(beanName, mbd, args);
利用工厂方法或者对象的构造器创建出 Bean 实例。
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
调用 MergedBeanDefinitionPostProcessor 的 postProcessMergedBeanDefinition(mbd, beanType, beanName);。
Bean 属性赋值:
populateBean(beanName, mbd, instanceWrapper);
拿到 InstantiationAwareBeanPostProcessor 后置处理器 postProcessAfterInstantiation(),拿到 InstantiationAwareBeanPostProcessor 后置处理器 postProcessPropertyValues()。
为 Bean 属性赋值,为属性利用 setter 方法等进行赋值:
applyPropertyValues(beanName, mbd, bw, pvs);
Bean 初始化:
initializeBean(beanName, exposedObject, mbd);
执行 Aware 接口方法:
invokeAwareMethods(beanName, bean);
执行 xxxAware 接口的方法 BeanNameAware\BeanClassLoaderAware\BeanFactoryAware。
执行后置处理器初始化之前:
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);BeanPostProcessor.postProcessBeforeInitialization();
执行初始化方法:
invokeInitMethods(beanName, wrappedBean, mbd);
是否是 InitializingBean 接口的实现,执行接口规定的初始化,是否自定义初始化方法。
执行后置处理器初始化之后,applyBeanPostProcessorsAfterInitialization 也就是 BeanPostProcessor.postProcessAfterInitialization()。
注册 Bean 的销毁方法:
registerDisposableBeanIfNecessary(beanName, bean, mbd);
将创建的 Bean 添加到缓存中 singletonObjects。
finishRefresh 完成容器刷新
- 初始化生命周期处理器(LifecycleProcessor),先从 BeanFactory 中按类型获取,如果没有就新建一个 DefaultLifecycleProcessor,并注册进 BeanFactory。
- 获取上一步注册的生命周期处理器,回调其 onRefresh 方法。
- 发布容器刷新事件,即 ContextRefreshedEvent。
流程图详解
简述
Spring 容器在启动的时候,先会保存所有注册进来的 Bean 的定义信息:
- xml 注册 bean:<bean>
- 注解注册 Bean:@Service、@Component、@Bean、xxx
Spring 容器会合适的时机创建这些 Bean:
- 用到这个 bean 的时候,利用 getBean 创建 bean,创建好以后保存在容器中。
- 统一创建剩下所有的 bean 的时候 finishBeanFactoryInitialization()。
后置处理器 BeanPostProcessor
每一个 bean 创建完成,都会使用各种后置处理器进行处理,来增强 bean 的功能。
- AutowiredAnnotationBeanPostProcessor:处理自动注入
- AnnotationAwareAspectJAutoProxyCreator:来做 AOP 功能
- ....
- 增强的功能注解:AsyncAnnotationBeanPostProcessor
- ....
事件驱动模型
- ApplicationListener:事件监听
- ApplicationEventMulticaster:事件派发
本文暂时没有评论,来添加一个吧(●'◡'●)