上一篇我们聊了Springboot的run方法,今天我们聊下关于容器刷新(refresh)
本文很长,请各位同学要忍一下~~~
好了,废话不多说,直接开干 !!!
1.refresh 主方法 (重要)
``` java public void refresh() throws BeansException, IllegalStateException { //加锁 防止出现其他线程也来刷新容器 synchronized(this.startupShutdownMonitor) { // 1.1 上下文刷新前的一些准备工作。如记录容器的启动时间、标记“已启动”状态、处理配置文件中的占位符等 this.prepareRefresh(); /* 1.2 创建 BeanFactory(DefaultListableBeanFactory) 并设置序列化id, 其用来加载 Bean 定义、注册 Bean 等 */ ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); // 1.3 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean this.prepareBeanFactory(beanFactory);
try {
/*
1.4
允许在上下文 子类中对 beanFactory进行 (后置处理)
【这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口,
那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。】
这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
*/
this.postProcessBeanFactory(beanFactory);
//1.5 Bean工厂的后置处理器,BeanFactoryPostProcessor(触发时机:bean定义 注册之后; bean实例化之前)
//简单来说就是调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
this.invokeBeanFactoryPostProcessors(beanFactory);
// 1.6 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
// 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
// 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
this.registerBeanPostProcessors(beanFactory);
//国际化相关 (略)
this.initMessageSource();
//1.7 初始化当前 ApplicationContext 的事件广播器 (略)
this.initApplicationEventMulticaster();
//1.8 具体的子类可以在这里初始化一些特殊的 Bean
this.onRefresh();
//1.9 注册事件监听器,监听器需要实现 ApplicationListener 接口 (略)
this.registerListeners();
//2.0 初始化所有的 singleton beans(lazy-init 的除外)(重要)
this.finishBeanFactoryInitialization(beanFactory);
// 发布 ApplicationContext 初始化完成事件
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
//销毁bean
this.destroyBeans();
//清除缓存
this.cancelRefresh(var9);
//抛出异常
throw var9;
} finally {
//重置 Spring 中的常见内省缓存,因为我们可能不再需要单例 bean 的元数据......
this.resetCommonCaches();
}
}
} ```
2. 接下来 将把以上流程展开
上下文刷新前的一些准备工作。如记录容器的启动时间、标记“已启动”状态、处理配置文件中的占位符等
```java protected void prepareRefresh() { // 记录启动时间 this.startupDate = System.currentTimeMillis(); this.closed.set(false); // 标记状态 this.active.set(true); if (this.logger.isDebugEnabled()) { if (this.logger.isTraceEnabled()) { this.logger.trace("Refreshing " + this); } else { this.logger.debug("Refreshing " + this.getDisplayName()); } }
this.initPropertySources(); //校验必须配置 this.getEnvironment().validateRequiredProperties(); if (this.earlyApplicationListeners == null) { this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners); } else { this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); }
this.earlyApplicationEvents = new LinkedHashSet(); } ```
创建 BeanFactory(DefaultListableBeanFactory) 并设置序列化id,其用来加载 Bean 定义、注册 Bean 等
java protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // 关闭旧的 BeanFactory (如果有),创建新的 BeanFactory(DefaultListableBeanFactory) 并设置序列化id,其用来加载 Bean 定义、注册 Bean 等 this.refreshBeanFactory(); // getBeanFactory BeanFactory实际为 DefaultListableBeanFactory 。 return this.getBeanFactory(); }
这里我们附一张 DefaultListableBeanFactory 类图,关于他 可以自行谷歌一下
设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean (prepareBeanFactory)
```java protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { //设置类加载器 beanFactory.setBeanClassLoader(this.getClassLoader()); //beanFactory的表达式语言处理器,Spring3增加了表达式语言的支持,
//默认可以使用#{bean.xxx}的形式来调用相关属性值 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); //设置PropertyEditorRegistrar,通过PropertyEditor将xml解析出来的bean属性(字符串)和相应的java类型做转换 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
/*
添加后置处理器ApplicationContextAwareProcessor,在Bean初始化后自动执行各Aware接口的set方法
实现了 Aware 接口的 beans 在初始化的时候,这个 processor 将会回调,
这个我们很常用,如我们会为了获取 ApplicationContext 而 implement ApplicationContextAware
注意:它不仅仅回调 ApplicationContextAware,
还会负责回调 EnvironmentAware、ResourceLoaderAware 等,看下源码就清楚了
*/
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//忽略依赖了这几个接口的bean
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
/*
为特殊的几个 bean 赋值
包括BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
*/
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//在 bean 实例化后,如果是 ApplicationListener 的子类,
//那么将其添加到 listener 列表中,可以理解成:注册 事件监听器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//如果存在loadTimeWeaver这个Bean,则增加对应的后置处理器
if (beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
//添加默认的系统环境bean (如果没有的话)
if (!beanFactory.containsLocalBean("environment")) {
beanFactory.registerSingleton("environment", this.getEnvironment());
}
if (!beanFactory.containsLocalBean("systemProperties")) {
beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean("systemEnvironment")) {
beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
}
} ```
java //空方法 专门为子类提供用于扩展 ,此时所有的 Bean 都加载、注册完成了,但是都还没有初始化, //这一步可以修改 bean 定义或者增加自定义的 bean。 protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { }
此时所有的 Bean 都加载、注册完成了,但是都还没有初始化
调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
(可以实现 BeanDefinitionRegistryPostProcessor接口 和 BeanFactoryPostProcessor接口 来扩展)
```java protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { //开始执行beanFactoryPostProcessor对应实现类,需要知道的是beanFactoryPostProcessor是spring的扩展接口,在刷新容器之前,该接口可以用来修改bean元数据信息 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors()); if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); }
} ```
紧接着我们看看 invokeBeanFactoryPostProcessors 做了什么
```java public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {
Set processedBeans = new HashSet<>();
//可以看到 这个方法是先处理 BeanDefinitionRegistryPostProcessor的实现, //然后再处理BeanFactoryPostProcessor的实现, //这也是为什么我们定义的扩展点 BeanDefinitionRegistryPostProcessorPoint先打印, //BeanFactoryPostProcessorPoint后打印的原因 if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List regularPostProcessors = new ArrayList<>(); List registryProcessors = new ArrayList<>(); //开始遍历三个内部类,如果属于BeanDefinitionRegistryPostProcessor子类,加入到bean注册的集合,否则加入到regularPostProcessors for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } }
List currentRegistryProcessors = new ArrayList<>();
//通过BeanDefinitionRegistryPostProcessor获取到对应的处理类“org.springframework.context.annotation.internalConfigurationAnnotationProcessor”,但是需要注意的是这个类在springboot中搜索不到,这个类的完全限定名在AnnotationConfigEmbeddedWebApplicationContext中,在进行初始化的时候会装配几个类,在创建AnnotatedBeanDefinitionReader对象的时候会将该类注册到bean对象中,此处可以看到internalConfigurationAnnotationProcessor为bean名称,容器中真正的类是ConfigurationClassPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//首先执行类型为PriorityOrdered的BeanDefinitionRegistryPostProcessor
//PriorityOrdered类型表明为优先执行
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//获取对应的bean
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//用来存储已经执行过的BeanDefinitionRegistryPostProcessor
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//开始执行装配逻辑
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
//其次执行类型为Ordered的BeanDefinitionRegistryPostProcessor
//Ordered表明按顺序执行
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
//循环中执行类型不为PriorityOrdered,Ordered类型的BeanDefinitionRegistryPostProcessor
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
//执行父类方法,优先执行注册处理类
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//执行有规则处理类
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else { invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); }
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List priorityOrderedPostProcessors = new ArrayList<>(); List orderedPostProcessorNames = new ArrayList<>(); List nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } }
sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
List orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
List nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
beanFactory.clearMetadataCache(); } ```
方法有点长。。该方法中的方法不再展开,具体看上边代码中的注释即可。
另外: 我在项目中定义了多个扩展点 在这里应该是会加载 BeanFactoryPostProcessorPoint , BeanDefinitionRegistryPostProcessorPoint这俩扩展点的,下面我们截图看下。
关于扩展点的代码 在我的github项目中: https://github.com/598572/xzll
走到方法最后 我们来看看我们自定义的扩展点哈,从下图可以看到 我们自定义的两个扩展点 都被Spring管理起来了
我们看下执行完 invokeBeanFactoryPostProcessors (我们自定义的扩展点)的输出哈
Spring的扩展点我个人认为是个很重要的东西,熟练使用这些特性,将会给你带来很大的遍历(项目中也经常会有这样的场景)
1. 回调符合要求的BeanDefinitionRegistryPostProcessor实现并向容器内添加bean类型等定义。
2. 回调符合要求的BeanFactoryPostProcessor实现并向容器内bean做定义、添加属性等操作。
将bean后置处理器(BeanPostProcessor)排序然后注册到容器中。
实现 BeanPostProcessor接口
```java
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); List priorityOrderedPostProcessors = new ArrayList(); List internalPostProcessors = new ArrayList(); List orderedPostProcessorNames = new ArrayList(); List nonOrderedPostProcessorNames = new ArrayList(); String[] var8 = postProcessorNames; int var9 = postProcessorNames.length;
String ppName;
BeanPostProcessor pp;
for(int var10 = 0; var10 < var9; ++var10) {
ppName = var8[var10];
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
List orderedPostProcessors = new ArrayList();
Iterator var14 = orderedPostProcessorNames.iterator();
while(var14.hasNext()) {
String ppName = (String)var14.next();
BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors);
List nonOrderedPostProcessors = new ArrayList();
Iterator var17 = nonOrderedPostProcessorNames.iterator();
while(var17.hasNext()) {
ppName = (String)var17.next();
pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors);
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
} ```
上面的代码大致就是根据不同实现接口,排序、分批注册bean后置处理器其实和
invokeBeanFactoryPostProcessors差不多 只不过 invokeBeanFactoryPostProcessors是针对 实现了BeanFactoryPostProcessors接口的类,而registerBeanPostProcessors是针对 实现了BeanPostProcessor接口的类
所以我们可以根据需要在这两处扩展一下,比如设置、添加,修改bean的属性,对bean进行校验等,比如我们实际案例中,有个场景是对配置类 a (标有@ConfigurationProperties)的配置类,来进行属性校验。
如下是我定义的扩展点 BeanPostProcessPoint 演示
通过源码可以看出该方法实现逻辑与 initMessageSource 基本相同,其步骤如下:查找是否有 name 为 applicationEventMulticaster 的 bean,如果有则放到容器里,如果没有,初始化一个系统默认的 SimpleApplicationEventMulticaster 对象放入容器。
模板方法,可用于 refresh 动作的扩展,默认为空实现。在 SpringBoot 中主要用于启动内嵌的 Web 服务器toomcat。
注册监听器,找出系统中的 ApplicationListener 对象,注册到时间广播器中。如果有需要提前进行广播的事件,则执行广播
environment
、systemProperties
等。特点: 长,逻辑比较多,这里推荐一篇写的很详细的文章 https://javadoop.com/post/spring-ioc 我个人觉得写的很好。
如果只是实例化bean,肯定很简单,其实就是jdk原生的反射机制,而spring实例化bean的代码之所以让人觉得很难消化,根本原因在于中间的"干扰钩子"太多,几乎在bean实例化的每一个阶段(分得很细),都"嵌入"了一些回调机制,这就导致看源码的时候干扰非常多。虽说有些回调机制干扰比较大,但是这些回调却又缺一不可,因为有了这些回调机制,用户就可以自定义代码"入侵"到实例化的任意阶段(实现对应接口+覆写方法),如果习惯了这种设计模式,相信看源码会顺畅很多,自己写代码的时候也可以考虑使用这种回调机制,暴露"入侵"接口。
需要说明的是 在这一步 有很多的扩展点可用 关于扩展点的东西,见我的下一篇文章
剩下的就是初始化 singleton beans 了,我们知道它们是单例的,如果没有设置懒加载,那么 Spring 会在接下来初始化所有的 singleton beans。
```java // 判断有无ConversionService(bean属性类型转换服务接口),并初始化 protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) { beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class)); }
// 如果beanFactory中不包含EmbeddedValueResolver,则向其中添加一个EmbeddedValueResolver
// EmbeddedValueResolver作用; 解析bean中的占位符和表达式
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver((strVal) -> {
return this.getEnvironment().resolvePlaceholders(strVal);
});
}
// 初始化LoadTimeWeaverAware类型的bean
// LoadTimeWeaverAware: 加载Spring Bean时织入第三方模块,如AspectJ
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
String[] var3 = weaverAwareNames;
int var4 = weaverAwareNames.length;
for(int var5 = 0; var5 < var4; ++var5) {
String weaverAwareName = var3[var5];
this.getBean(weaverAwareName);
}
// 释放临时类加载器
beanFactory.setTempClassLoader((ClassLoader)null);
//没什么别的目的,因为到这一步的时候,Spring 已经开始预初始化 singleton beans 了,
//肯定不希望这个时候还出现 bean 定义解析、加载、注册
beanFactory.freezeConfiguration();
// 初始化其他的非延迟加载的单例bean(重要重要重要~ 重要的事情说三遍 嘿嘿 )
beanFactory.preInstantiateSingletons();
} ```
实例化 BeanFactory 中已经被注册但是未实例化的所有实例(懒加载的不需要实例化),主要操作是 BeanFactory 的 preInstantiateSingletons 方法。该方法分为两部分:
```java public void preInstantiateSingletons() throws BeansException { if (this.logger.isTraceEnabled()) { this.logger.trace("Pre-instantiating singletons in " + this); } //获取所有需要初始化的beanName 从 beanDefinitionNames集合中 List beanNames = new ArrayList(this.beanDefinitionNames); Iterator var2 = beanNames.iterator();
//下面这个循环,触发所有的非懒加载的 singleton beans 的初始化操作
while(true) {
String beanName;
Object bean;
do {
while(true) {
RootBeanDefinition bd;
do {
do {
do {
if (!var2.hasNext()) {
var2 = beanNames.iterator();
while(var2.hasNext()) {
beanName = (String)var2.next();
Object singletonInstance = this.getSingleton(beanName);
// bean初始化后的回调方法。跟前面讲到的postProcessBeanDefinitionRegistry原理相似。
// 用户可实现SmartInitializingSingleton接口+覆写afterSingletonsInstantiated方法达到自定义回调逻辑(在我的项目中也这么测试了)
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, this.getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
return;
}
beanName = (String)var2.next();
bd = this.getMergedLocalBeanDefinition(beanName);
} while(bd.isAbstract());
} while(!bd.isSingleton());
} while(bd.isLazyInit());
//处理FactoryBean给其加上前缀 &
if (this.isFactoryBean(beanName)) {
bean = this.getBean("&" + beanName);
break;
}
this.getBean(beanName);
}
} while(!(bean instanceof FactoryBean));
FactoryBean> factory = (FactoryBean)bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
SmartFactoryBean var10000 = (SmartFactoryBean)factory;
((SmartFactoryBean)factory).getClass();
isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
} else {
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
}
if (isEagerInit) {
this.getBean(beanName);
}
}
} ``` 哇咔咔~~~ 一顿操作猛如虎??? 一个个while do看的我懵逼三连???哈哈
如下示例:我们自己写的service类(其实所有的非抽象 非懒加载的bean)都会在这里实例化 (先get没有的话才实例化哈)
紧接着我们看下代码 ```java protected T doGetBean(String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { //这里应该是别名的转换 String beanName = this.transformedBeanName(name); Object sharedInstance = this.getSingleton(beanName); Object bean; //如果从map总没获取到 并且args是空的话 那么 请看 getObjectForBeanInstance注释 if (sharedInstance != null && args == null) { if (this.logger.isTraceEnabled()) { if (this.isSingletonCurrentlyInCreation(beanName)) { this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } // 下面这个方法:如果是普通 Bean 的话,直接返回 sharedInstance, // 如果是 FactoryBean 的话,返回它创建后那个实例对象 bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null); } else { // 创建过了此 beanName 的 prototype 类型的 bean,那么抛异常, // 往往是因为陷入了循环引用 if (this.isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // 检查一下这个 BeanDefinition 在容器中是否存在 BeanFactory parentBeanFactory = this.getParentBeanFactory(); if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) { String nameToLookup = this.originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly); }
if (args != null) {
return parentBeanFactory.getBean(nameToLookup, args);
}
if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
return parentBeanFactory.getBean(nameToLookup);
}
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
/* 稍稍总结一下: 到这里的话,要准备创建 Bean 了,对于 singleton 的 Bean 来说,容器中还没创建过此 Bean; 对于 prototype 的 Bean 来说,本来就是要创建一个新的 Bean。 */ try { RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName); this.checkMergedBeanDefinition(mbd, beanName, args); String[] dependsOn = mbd.getDependsOn(); String[] var11;
// 先初始化依赖的所有 Bean,这个很好理解。
// 注意,这里的依赖指的是 depends-on 中定义的依赖
if (dependsOn != null) {
var11 = dependsOn;
int var12 = dependsOn.length;
for(int var13 = 0; var13 < var12; ++var13) {
String dep = var11[var13];
// 检查是不是有循环依赖,这里的循环依赖和我们前面说的循环依赖又不一样,
//这里肯定是不允许出现的,不然要乱套了.哈哈 肯定不能声明 a dependsOn b ,b dependsOn a,对吧?
if (this.isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//注册依赖关系 参数一: 被依赖项,参数二: beanName
this.registerDependentBean(dep, beanName);
try {
//获取依赖的bean
this.getBean(dep);
} catch (NoSuchBeanDefinitionException var24) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
}
}
}
//如果是单列的话 创建bean
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
//******* 创建bean ******
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
//多例的话 走这个if
var11 = null;
Object prototypeInstance;
try {
this.beforePrototypeCreation(beanName);
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
String scopeName = mbd.getScope();
Scope scope = (Scope)this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
this.beforePrototypeCreation(beanName);
Object var4;
try {
var4 = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
return var4;
});
bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException var23) {
throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var23);
}
}
} catch (BeansException var26) {
this.cleanupAfterBeanCreationFailure(beanName);
throw var26;
}
} // 最后,检查一下类型对不对,不对的话就抛异常,对的话就返回了 if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } else { return convertedBean; } } catch (TypeMismatchException var25) { if (this.logger.isTraceEnabled()) { this.logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var25); }
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
} else { return bean; } } ```
我们看下创建bean之前的一些参数 beanName, mbd,args都是什么 见下图:
(重要)
```java protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (this.logger.isTraceEnabled()) { this.logger.trace("Creating instance of bean '" + beanName + "'"); }
RootBeanDefinition mbdToUse = mbd;
Class> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
// 确保 BeanDefinition 中的 Class 被加载
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
//方法覆写相关
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException var9) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9);
}
Object beanInstance;
try {
// InstantiationAwareBeanPostProcessor 这个地方也可以扩展 具体见上边提到的扩展点项目代码
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if (beanInstance != null) {
return beanInstance;
}
} catch (Throwable var10) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
}
try {
//开始创建bean
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
} catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
throw var7;
} catch (Throwable var8) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
}
} ```
```java protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName); }
if (instanceWrapper == null) {
//<1>. 下边将会展开
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable var17) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
}
mbd.postProcessed = true;
}
}
// 下面这块代码是为了解决循环依赖的问题,以后有时间,我再对循环依赖这个问题进行解析吧
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
Object exposedObject = bean;
try {
//这一步也是非常关键的,这一步负责属性装配,因为前面的实例只是实例化了,并没有设值,这里就是设值
//<2>. 下边将会展开
this.populateBean(beanName, mbd, instanceWrapper);
// 还记得 init-method 吗?还有 InitializingBean 接口
// 这里就是处理 bean 初始化完成后的各种回调
//<3>. 下边将会展开
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable var18) {
if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
throw (BeanCreationException)var18;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
}
if (earlySingletonExposure) {
Object earlySingletonReference = this.getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
String[] dependentBeans = this.getDependentBeans(beanName);
Set actualDependentBeans = new LinkedHashSet(dependentBeans.length);
String[] var12 = dependentBeans;
int var13 = dependentBeans.length;
for(int var14 = 0; var14 < var13; ++var14) {
String dependentBean = var12[var14];
if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
try {
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
} catch (BeanDefinitionValidationException var16) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
}
} ```
<1>
处 是如何创建bean的```java protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { Class> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]); //检查类的访问权限 if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } else { Supplier> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) {
return this.obtainFromSupplier(instanceSupplier, beanName);
} else if (mbd.getFactoryMethodName() != null) {
//采用工厂方法实例化,注意,不是 FactoryBean
return this.instantiateUsingFactoryMethod(beanName, mbd, args);
} else {
// 如果不是第一次创建,比如第二次创建 prototype bean。
// 这种情况下,我们可以从第一次创建知道,采用无参构造函数,还是构造函数依赖注入 来完成实例化
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized(mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
// 构造函数依赖注(无参构造)
return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
} else {
// 判断是否采用有参构造函数
Constructor>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {
ctors = mbd.getPreferredConstructors();
return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd);
} else {
//构造函数依赖注 (有参构造 )
return this.autowireConstructor(beanName, mbd, ctors, args);
}
}
}
}
} ```
```java public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { if (!bd.hasMethodOverrides()) { Constructor constructorToUse; synchronized(bd.constructorArgumentLock) { constructorToUse = (Constructor)bd.resolvedConstructorOrFactoryMethod; if (constructorToUse == null) { Class> clazz = bd.getBeanClass(); if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface"); }
try {
if (System.getSecurityManager() != null) {
clazz.getClass();
constructorToUse = (Constructor)AccessController.doPrivileged(() -> {
return clazz.getDeclaredConstructor();
});
} else {
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
} catch (Throwable var9) {
throw new BeanInstantiationException(clazz, "No default constructor found", var9);
}
}
}
//利用构造来进行实例化 (反射)
return BeanUtils.instantiateClass(constructorToUse, new Object[0]);
} else {
// 存在方法覆写,利用 CGLIB 来完成实例化,需要依赖于 CGLIB 生成子类,这里就不展开了。
// 注意: 如果不使用 CGLIB 的话,存在 override 的情况 JDK 并没有提供相应的实例化支持
return this.instantiateWithMethodInjection(bd, beanName, owner);
}
} ```
接着跟进去
继续跟进去
继续
ok到此 我们已经把bean的实例化(也就是 createBeanInstance方法 )看完了 。注意 旁枝细节的就略过了看主要的就好
```java protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { // bean 实例的所有属性都在这里了 PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) { if (!pvs.isEmpty()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { return; } }
// 到这步的时候,bean 实例化完成(通过工厂方法或构造方法),但是还没开始属性设值, // InstantiationAwareBeanPostProcessor 的实现类可以在这里对 bean 进行状态修改, boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 如果返回 false,代表不需要进行后续的属性设值,也不需要再经过其他的 BeanPostProcessor 的处理 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } }
if (!continueWithPropertyPopulation) { return; }
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIREBYNAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIREBYTYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 通过名字找到所有属性值,如果是 bean 依赖,先初始化依赖的 bean。记录依赖关系
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 通过类型装配。复杂一些
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCYCHECKNONE);
if (hasInstAwareBpps || needsDepCheck) { PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 这里有个非常有用的 BeanPostProcessor 进到这里: AutowiredAnnotationBeanPostProcessor // 对采用 @Autowired、@Value 注解的依赖进行设值 pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } // 设置 bean 实例的属性值 applyPropertyValues(beanName, mbd, bw, pvs); } ```
@Autoware时候根据类型注入和根据name注入 是不是实际开发中都使用过呀
对采用 @Autowired、@Value 注解的依赖进行设值
```java protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { invokeAwareMethods(beanName, bean); return null; } }, getAccessControlContext()); } else { // 如果 bean 实现了 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware 接口,那么进行回调 invokeAwareMethods(beanName, bean); }
Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // BeanPostProcessor 的 postProcessBeforeInitialization 回调 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); }
try { // 处理 bean 中定义的 init-method, // 或者如果 bean 实现了 InitializingBean 接口,调用 afterPropertiesSet() 方法 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); }
if (mbd == null || !mbd.isSynthetic()) { // BeanPostProcessor 的 postProcessAfterInitialization 回调 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
```
总结:
说明: 关于扩展点的内容 请见我的下一篇文章 ~
本文完,如有错误恳请指正
本文部分参考了这位大佬的博文: https://javadoop.com/post/spring-ioc