首页 > 编程语言 >Spring Bean生命周期——从源码角度详解Spring Bean的生命周期(上)

Spring Bean生命周期——从源码角度详解Spring Bean的生命周期(上)

时间:2023-01-26 15:02:59浏览次数:43  
标签:生命周期 String mbd Spring beanName bean Bean new null


文章目录

  • ​​写在前面​​
  • ​​一、Spring Bean 元信息配置阶段​​
  • ​​1、使用xml方式配置BeanDefinition​​
  • ​​代码实例​​
  • ​​2、使用Properties 资源配置BeanDefinition​​
  • ​​代码实例​​
  • ​​Map或Properties的写法解释​​
  • ​​3、使用Groovy配置BeanDefinition​​
  • ​​4、使用注解配置BeanDefinition​​
  • ​​5、使用API配置BeanDefinition​​
  • ​​二、Spring Bean 元信息解析阶段​​
  • ​​1、面向资源 BeanDefinition 解析​​
  • ​​2、面向注解 BeanDefinition 解析​​
  • ​​代码实例​​
  • ​​3、源码分析​​
  • ​​BeanDefinitionReader​​
  • ​​AnnotatedBeanDefinitionReader​​
  • ​​三、Spring Bean 注册阶段​​
  • ​​1、注册普通BeanDefinition​​
  • ​​2、(拓展)注册单体bean​​
  • ​​3、(拓展)Spring 注册內建 BeanDefintion​​
  • ​​四、Spring BeanDefinition 合并阶段​​
  • ​​1、实例​​
  • ​​2、源码分析​​
  • ​​3、分析总结​​
  • ​​五、Spring Bean Class 加载阶段​​
  • ​​1、源码分析​​
  • ​​2、总结​​
  • ​​六、Spring Bean 实例化阶段​​
  • ​​1、实例化前阶段​​
  • ​​代码实例​​
  • ​​源码分析​​
  • ​​总结分析​​
  • ​​2、Spring自身的Bean实例化阶段​​
  • ​​源码分析​​
  • ​​源码分析-简单用无参构造器实例化​​
  • ​​源码分析-通过构造器进行实例化​​
  • ​​总结分析​​
  • ​​3、实例化后阶段​​
  • ​​代码实例​​
  • ​​源码分析​​
  • ​​总结分析​​

写在前面

​​Spring Bean生命周期——从源码角度详解Spring Bean的生命周期(上)​​

​​Spring Bean生命周期——从源码角度详解Spring Bean的生命周期(下)​​

关于spring bean的生命周期的使用,之前已经介绍过:
​spring系列-注解驱动原理及源码-bean生命周期​​

以及详细介绍过Spring Bean相关的源码:
​深入浅出弄明白Spring的BeanDefinition,Spring-Beans部分源码分析​​

本文在此做更深入得讨论和研究,将源码吃透!

一、Spring Bean 元信息配置阶段

1、使用xml方式配置BeanDefinition

代码实例

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import java.util.Map;

public class BeanFactoryAsIoCContainerDemo {

public static void main(String[] args) {
// 创建 BeanFactory 容器
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
// XML 配置文件 ClassPath 路径
String location = "classpath:/META-INF/beans.xml";
// 加载配置
int beanDefinitionsCount = reader.loadBeanDefinitions(location);
System.out.println("Bean 定义加载的数量:" + beanDefinitionsCount);
// 依赖查找集合对象
lookupCollectionByType(beanFactory);
}

private static void lookupCollectionByType(BeanFactory beanFactory) {
if (beanFactory instanceof ListableBeanFactory) {
ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
Map<String, User> users = listableBeanFactory.getBeansOfType(User.class);
System.out.println("查找到的所有的 User 集合对象:" + users);
}
}

}

在xml中可以配置自定义的bean:

<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">

<bean id="user" class="com.test.User">
<property name="id" value="1"/>
<property name="name" value="张三"/>
<property name="city" value="青岛"/>
</bean>

</beans>

2、使用Properties 资源配置BeanDefinition

代码实例

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.EncodedResource;

/**
* 使用properties 配置Bean 元信息示例
*/
public class BeanMetadataConfigurationDemo {

public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 实例化基于 Properties 资源 BeanDefinitionReader
PropertiesBeanDefinitionReader beanDefinitionReader = new PropertiesBeanDefinitionReader(beanFactory);
String location = "META-INF/user.properties";
// 基于 ClassPath 加载 properties 资源
Resource resource = new ClassPathResource(location);
// 指定字符编码 UTF-8
EncodedResource encodedResource = new EncodedResource(resource, "UTF-8");
int beanNumbers = beanDefinitionReader.loadBeanDefinitions(encodedResource);
System.out.println("已加载 BeanDefinition 数量:" + beanNumbers);
// 通过 Bean Id 和类型进行依赖查找
User user = beanFactory.getBean("user", User.class);
System.out.println(user);
}

}

user.properties:

user.(class) = com.test.domain.User
user.id = 001
user.name = 张三

Map或Properties的写法解释

employee.(class)=MyClass       // MyClass的类全路径
employee.(abstract)=true // 这个bean不能直接实例化
employee.group=Insurance // 配置属性
employee.usesDialUp=false // 配置属性(可能被覆盖)

salesrep.(parent)=employee // 源自employee的bean定义,继承employee属性配置等等
salesrep.(lazy-init)=true // bean懒加载
salesrep.manager(ref)=tony // 对tony这个bean的引用
salesrep.department=Sales // 配置属性

techie.(parent)=employee // 源自employee的bean定义,继承employee属性配置等等
techie.(scope)=prototype // bean的scope
techie.manager(ref)=jeff // 引用另一个bean
techie.department=Engineering // 属性
techie.usesDialUp=true // 属性,覆盖父bean的属性值

ceo.$0(ref)=secretary // 注入secretary的第0个构造方法参数
ceo.$1=1000000 // 注入1000000第1个构造方法参数值

3、使用Groovy配置BeanDefinition

重口味的程序员可能觉得这是吃饱了没事儿撑的用groovy进行bean配置。但是想下maven和gradle,maven基于xml,gradle基于groovy。同样的配置,在gradle中显得十分精炼,同时,因为gradle使用了groovy这样一种语言,而不是xml这种文件,使其更加灵活,在定义task方面会更加的方便。

但是,使用Groovy配置Bean终究不是主流,感兴趣的小伙伴可以自行研究。此处略。

4、使用注解配置BeanDefinition

// @Bean
@Bean(name = {"user", "ts-user"})
public User user() {
User user = new User();
user.setId(1L);
user.setName("张三");
return user;
}

// @Component(及其派生注解比如(@Service、@Controller、@Repository))
@Component // 定义当前类作为 Spring Bean(组件)
public static class Config {

// @Import
// 通过 @Import 来进行导入
@Import(Config.class)
@Component
public class AnnotationBeanDefinitionDemo {

5、使用API配置BeanDefinition

1、配置类方式:AnnotatedBeanDefinitionReader#register(Class…)

// 创建 BeanFactory 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 注册 Configuration Class(配置类)
applicationContext.register(AnnotationBeanDefinitionDemo.class);
// 启动 Spring 应用上下文
applicationContext.refresh();

2、使用BeanDefinitionRegistry 注册

// BeanDefinitionRegistry 就是用来注册bean的
public static void registerUserBeanDefinition(BeanDefinitionRegistry registry, String beanName) {
BeanDefinitionBuilder beanDefinitionBuilder = genericBeanDefinition(User.class);
beanDefinitionBuilder
.addPropertyValue("id", 1L)
.addPropertyValue("name", "张三");

// 判断如果 beanName 参数存在时
if (StringUtils.hasText(beanName)) {
// 注册 BeanDefinition
registry.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());
} else {
// 非命名 Bean 注册方法(参考下面Bean命名-自动命名)
BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinitionBuilder.getBeanDefinition(), registry);
}
}

public static void registerUserBeanDefinition(BeanDefinitionRegistry registry) {
registerUserBeanDefinition(registry, null);
}

二、Spring Bean 元信息解析阶段

1、面向资源 BeanDefinition 解析

使用BeanDefinitionReader以及 XML 解析器 - BeanDefinitionParser 解析xml文件。

前面已经介绍过,这里就不重复介绍了。

2、面向注解 BeanDefinition 解析

使用AnnotatedBeanDefinitionReader 解析注解。

代码实例

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;

/**
* 注解 BeanDefinition 解析示例
*/
public class AnnotatedBeanDefinitionParsingDemo {

public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 基于 Java 注解的 AnnotatedBeanDefinitionReader 的实现
AnnotatedBeanDefinitionReader beanDefinitionReader = new AnnotatedBeanDefinitionReader(beanFactory);
int beanDefinitionCountBefore = beanFactory.getBeanDefinitionCount();
// 注册当前类(非 @Component class)
beanDefinitionReader.register(AnnotatedBeanDefinitionParsingDemo.class);
int beanDefinitionCountAfter = beanFactory.getBeanDefinitionCount();
int beanDefinitionCount = beanDefinitionCountAfter - beanDefinitionCountBefore;
System.out.println("已加载 BeanDefinition 数量:" + beanDefinitionCount);
// 普通的 Class 作为 Component 注册到 Spring IoC 容器后,通常 Bean 名称为 annotatedBeanDefinitionParsingDemo
// Bean 名称生成来自于 BeanNameGenerator,注解实现 AnnotationBeanNameGenerator
AnnotatedBeanDefinitionParsingDemo demo = beanFactory.getBean("annotatedBeanDefinitionParsingDemo",
AnnotatedBeanDefinitionParsingDemo.class);
System.out.println(demo);
}
}

3、源码分析

BeanDefinitionReader

通过资源解析BeanDefinition,我们需要将资源的路径传给BeanDefinitionReader,然后进行资源的解析。

通常来说,总共有三种资源解析的BeanDefinitionReader:

  • GroovyBeanDefinitionReader:解析groovy
  • PropertiesBeanDefinitionReader:解析property配置文件
  • XmlBeanDefinitionReader:解析xml文件

以上三种方式我们都了解过了。

这三个BeanDefinitionReader,都继承了AbstractBeanDefinitionReader,而AbstractBeanDefinitionReader又实现了BeanDefinitionReader,所以,这三者只是资源的读取方式不同,其他基本大同小异。

AnnotatedBeanDefinitionReader

而通过注解解析BeanDefinition,是通过AnnotatedBeanDefinitionReader 进行解析的,这个类与前面使用资源解析的Reader完全不同,它不需要加载配置文件资源。

AnnotatedBeanDefinitionReader是一个完全独立的类,它没有继承和实现任何类或者接口,它通过register方法,将类解析成BeanDefinition。

它支持注解方式,而基于注解的方式,在springboot中大量使用,也是日常开发的主流。

三、Spring Bean 注册阶段

1、注册普通BeanDefinition

Spring Bean的注册,就是基于BeanDefinition 注册接口BeanDefinitionRegistry来注册的。

BeanDefinitionRegistry接口为BeanDefinition 提供了基础的增删改查方法。

而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,作为Bean注册的一个顶级类。

我们一起来分析一下DefaultListableBeanFactory的registerBeanDefinition方法:

// org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition
@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");

// 做了一下类型转换,因为spring5.0、5.1之后,很多方法提升到了AbstractBeanDefinition
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}

// 先从map中获取,判断bean名称是否重复
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
// 有个开关,判断是否允许bean名称重复,默认是允许重复的
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);
}
// bean完全不存在
else {
// 判断当前bean是否已经开始创建了
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; // 是一个ArrayList,只存储bean名称,使用Arraylist保证bean有序
removeManualSingletonName(beanName);
}
}
else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName); // 使用Arraylist保证bean有序
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}

if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}

通过以上Bean注册的源码我们可以看出,BeanDefinition信息存在beanDefinitionMap中,它是一个ConcurrentHashMap。

我们都知道ConcurrentHashMap是无序的,这里还用了一个beanDefinitionNames 存储bean的名称,它是一个ArrayList是有序的,目的就是记录bean的注册顺序。

private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(256);
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap(64);
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap(64);
private volatile List<String> beanDefinitionNames = new ArrayList(256);

2、(拓展)注册单体bean

关于单体的bean,更多信息我们请移步:
​SpringIOC容器的依赖来源都有哪些?这次一起捋清楚~​​

单体Bean通过SingletonBeanRegistry的registerSingleton来注册。DefaultSingletonBeanRegistry实现了SingletonBeanRegistry接口。

单体Bean注册就很简单了,它不会通过BeanDefinition来进行注册:

// org.springframework.beans.factory.support.DefaultListableBeanFactory#registerSingleton
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
super.registerSingleton(beanName, singletonObject);
updateManualSingletonNames(set -> set.add(beanName), set -> !this.beanDefinitionMap.containsKey(beanName));
clearByTypeCache();
}

// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#registerSingleton
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
Assert.notNull(beanName, "Bean name must not be null");
Assert.notNull(singletonObject, "Singleton object must not be null");
synchronized (this.singletonObjects) {
Object oldObject = this.singletonObjects.get(beanName);
if (oldObject != null) {
throw new IllegalStateException("Could not register object [" + singletonObject +
"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
}
addSingleton(beanName, singletonObject);
}
}

// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}

我们可以看到,单体bean的注册比较简单,最终只是将bean对象存到了singletonObjects,它是一个ConcurrentHashMap,key是bean的名称,value是bean的对象。

3、(拓展)Spring 注册內建 BeanDefintion

关于Spring 注册內建 BeanDefintion,更多请移步一、3、Spring 內建 BeanDefintion:

​​SpringIOC容器的依赖来源都有哪些?这次一起捋清楚~​​

四、Spring BeanDefinition 合并阶段

1、实例

在使用资源配置bean时(xml、groovy、property),可以指定bean的父类,这样可以完全继承父类所有的属性值。

以xml为例:

public class User {

private Long id;

private String name;

private City city;
// 略
public class ChildUser extends User {

private String address;

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

@Override
public String toString() {
return "ChildUser{" +
"address='" + address + '\'' +
"} " + super.toString();
}
}
<!-- Root BeanDefinition 不需要合并,不存在 parent -->
<!-- 普通 beanDefinition GenericBeanDefinition -->
<!-- 经过合并后 GenericBeanDefinition 变成 RootBeanDefinition -->
<bean id="user" class="com.test.domain.User">
<property name="id" value="1"/>
<property name="name" value="张三"/>
<property name="city" value="BEIJING"/>
</bean>

<!-- 普通 beanDefinition GenericBeanDefinition -->
<!-- 合并后 GenericBeanDefinition 变成 RootBeanDefinition,并且覆盖 parent 相关配置-->
<!-- primary = true , 增加了一个 address 属性 -->
<bean id="childUser" class="com.test.domain.ChildUser" parent="user"
primary="true">
<property name="address" value="北京"/>
</bean>

在xml中配置bean时,使用parent属性,就可以指定父bean的名称,继承父bean的所有属性。

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.EncodedResource;

/**
* BeanDefinition 合并示例
*/
public class MergedBeanDefinitionDemo {

public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 基于 XML 资源 BeanDefinitionReader 实现
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
String location = "META-INF/dependency-lookup-context.xml";
// 基于 ClassPath 加载 XML 资源
Resource resource = new ClassPathResource(location);
// 指定字符编码 UTF-8
EncodedResource encodedResource = new EncodedResource(resource, "UTF-8");
int beanNumbers = beanDefinitionReader.loadBeanDefinitions(encodedResource);
System.out.println("已加载 BeanDefinition 数量:" + beanNumbers);
// 通过 Bean Id 和类型进行依赖查找
User user = beanFactory.getBean("user", User.class);
System.out.println(user);

User superUser = beanFactory.getBean("childUser", User.class);
System.out.println(superUser);
}
}

通过结果我们也可以看出:childUser继承了user的所有属性。

2、源码分析

上面实例我们可以看出,在定义bean时,user是没有父类的,所以在定义BeanDefinition时,Spring认为User是一个RootBeanDefinition。

ChildUser继承了User,并且使用parent属性继承了user的所有属性值,所以Spring认为ChildUser是一个普通 beanDefinition(GenericBeanDefinition) ,并且是需要合并的。

在Spring中,RootBeanDefinition是不允许有自己的parent的:

// org.springframework.beans.factory.support.RootBeanDefinition#setParentName
@Override
public void setParentName(@Nullable String parentName) {
if (parentName != null) {
throw new IllegalArgumentException("Root bean cannot be changed into a child bean with parent reference");
}
}

而GenericBeanDefinition是可以设置其parent(可空)的:

// org.springframework.beans.factory.support.GenericBeanDefinition#setParentName
@Override
public void setParentName(@Nullable String parentName) {
this.parentName = parentName;
}

关于BeanDefinition合并,ConfigurableBeanFactory接口中有一个getMergedBeanDefinition方法,由方法注释我们可以知道,通过bean的名称会返回一个合并过的BeanDefinition,并且合并的过程中是一个递归的操作:

/**
* Return a merged BeanDefinition for the given bean name,
* merging a child bean definition with its parent if necessary.
* Considers bean definitions in ancestor factories as well.
* @param beanName the name of the bean to retrieve the merged definition for
* @return a (potentially merged) BeanDefinition for the given bean
* @throws NoSuchBeanDefinitionException if there is no bean definition with the given name
* @since 2.5
*/
BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

getMergedBeanDefinition方法只有一个实现,就是AbstractBeanFactory类:

// org.springframework.beans.factory.support.AbstractBeanFactory#getMergedBeanDefinition(java.lang.String)
@Override
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
String beanName = transformedBeanName(name);
// Efficiently check whether bean definition exists in this factory.
// 如果当前bean中没有BeanDefinition,并且父BeanFactory是ConfigurableBeanFactory,递归查找
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
}
// Resolve merged bean definition locally.
// 以上存在,从本地来找bean
return getMergedLocalBeanDefinition(beanName);
}
// org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
// 从map中找bean
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null && !mbd.stale) {
return mbd;
}
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}

// org.springframework.beans.factory.support.AbstractBeanFactory#getMergedBeanDefinition(java.lang.String, org.springframework.beans.factory.config.BeanDefinition)
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
return getMergedBeanDefinition(beanName, bd, null);
}

// org.springframework.beans.factory.support.AbstractBeanFactory#getMergedBeanDefinition(java.lang.String, org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.factory.config.BeanDefinition)
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) // 如果bd是innerBean,那containingBd是外层bean;如果bd是外层bean,containingBd是null。如果为空表示该bean是一个顶级的bean(bean是可以嵌套的)
throws BeanDefinitionStoreException {

synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
RootBeanDefinition previous = null;

// Check with full lock now in order to enforce the same merged instance.
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName); // 锁后查,保证数据的准确
}

if (mbd == null || mbd.stale) {
previous = mbd;
if (bd.getParentName() == null) { // 如果没有parent
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) { // Root不需要merge,它没有parent
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition(); // 复制一份
}
else { // 如果parent为null,又是GenericBeanDefinition,就直接变成RootBeanDefinition
mbd = new RootBeanDefinition(bd);
}
}
else { // 如果有parent
// Child bean definition: needs to be merged with parent.
BeanDefinition pbd;
try {
String parentBeanName = transformedBeanName(bd.getParentName()); // 名称规范化
if (!beanName.equals(parentBeanName)) {
// 查找父bean(父bean有可能也有父bean),这也是一个递归操作
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
// parent的bean层次性查找
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without an AbstractBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
mbd = new RootBeanDefinition(pbd); // 合并后的结果,返回一个RootBeanDefinition
mbd.overrideFrom(bd); // 将父类的属性、配置等等,覆写到子类
}

// Set default singleton scope, if not configured before.
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(SCOPE_SINGLETON);
}

// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}

// Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
if (previous != null) {
copyRelevantMergedBeanDefinitionCaches(previous, mbd);
}
return mbd;
}
}

overrideFrom方法用于将parent的BeanDefinition的信息赋给子类,有就覆盖,没有就增加:

// org.springframework.beans.factory.support.AbstractBeanDefinition#overrideFrom
public void overrideFrom(BeanDefinition other) {
if (StringUtils.hasLength(other.getBeanClassName())) {
setBeanClassName(other.getBeanClassName());
}
if (StringUtils.hasLength(other.getScope())) {
setScope(other.getScope());
}
setAbstract(other.isAbstract());
if (StringUtils.hasLength(other.getFactoryBeanName())) {
setFactoryBeanName(other.getFactoryBeanName());
}
if (StringUtils.hasLength(other.getFactoryMethodName())) {
setFactoryMethodName(other.getFactoryMethodName());
}
setRole(other.getRole());
setSource(other.getSource());
copyAttributesFrom(other);

if (other instanceof AbstractBeanDefinition) {
AbstractBeanDefinition otherAbd = (AbstractBeanDefinition) other;
if (otherAbd.hasBeanClass()) {
setBeanClass(otherAbd.getBeanClass());
}
if (otherAbd.hasConstructorArgumentValues()) {
getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
}
if (otherAbd.hasPropertyValues()) {
getPropertyValues().addPropertyValues(other.getPropertyValues());
}
if (otherAbd.hasMethodOverrides()) {
getMethodOverrides().addOverrides(otherAbd.getMethodOverrides());
}
Boolean lazyInit = otherAbd.getLazyInit();
if (lazyInit != null) {
setLazyInit(lazyInit);
}
setAutowireMode(otherAbd.getAutowireMode());
setDependencyCheck(otherAbd.getDependencyCheck());
setDependsOn(otherAbd.getDependsOn());
setAutowireCandidate(otherAbd.isAutowireCandidate());
setPrimary(otherAbd.isPrimary());
copyQualifiersFrom(otherAbd);
setInstanceSupplier(otherAbd.getInstanceSupplier());
setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed());
setLenientConstructorResolution(otherAbd.isLenientConstructorResolution());
if (otherAbd.getInitMethodName() != null) {
setInitMethodName(otherAbd.getInitMethodName());
setEnforceInitMethod(otherAbd.isEnforceInitMethod());
}
if (otherAbd.getDestroyMethodName() != null) {
setDestroyMethodName(otherAbd.getDestroyMethodName());
setEnforceDestroyMethod(otherAbd.isEnforceDestroyMethod());
}
setSynthetic(otherAbd.isSynthetic());
setResource(otherAbd.getResource());
}
else {
getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
getPropertyValues().addPropertyValues(other.getPropertyValues());
setLazyInit(other.isLazyInit());
setResourceDescription(other.getResourceDescription());
}
}

3、分析总结

总而言之,Spring BeanDefinition合并阶段,就是在RootBeanDefinition的基础上,添加或者修改成子类的属性。最终parentBeanDefinition和subBeanDefinition都一起成为了RootBeanDefinition,保存在mergedBeanDefinitions的缓存里。

没有继承的Bean定义最终会生成RootBeanDefinition,这种BeanDefinition不需要合并,禁止对setParentName方法设置值。而存在parent的Bean定义则生成的是普通的GenericBeanDefinition,需要合并parent的BeanDefinition属性。

AbstractBeanFactory的getMergedBeanDefinition(String beanName)方法提供了BeanDefinition的合并逻辑的实现。执行最终合并的是其中的mbd.overrideFrom(bd),将子bean和父bean的属性进行合并。

一开始不管有没有parent,都是GenericBeanDefinition,然后通过merge最终是所有的beanDefinition都会转换成RootBeanDefinition。

关于层次性依赖查找,请移步:
​spring依赖查找、依赖注入深入学习及源码分析​​

五、Spring Bean Class 加载阶段

关于java的类加载机制、双亲委派机制请移步:
​java类加载器、双亲委派、沙箱安全机制全都让你整明白(三万字,收藏慢慢啃)​​

1、源码分析

我们可以看到,BeanDefinition接口有对beanClass名称的set、get方法:

void setBeanClassName(@Nullable String beanClassName);

@Nullable
String getBeanClassName();

可见,BeanDefinition是存储了bean的Class名称的,它是用String来存储的。

我们继续看,当调用beanFactory.getBean()方法时,会最终执行AbstractBeanFactory的doGetBean方法,这个方法里面有个核心逻辑就是创建Singleton bean:

// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {

if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;

// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName); // 处理Bean的Class类
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}

// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}

try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}

try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
// org.springframework.beans.factory.support.AbstractBeanFactory#resolveBeanClass
@Nullable
protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
throws CannotLoadBeanClassException {

try {
// 判断BeanDefinition是否指定了beanClass,这里的beanClass是一个Object,不是上面说的beanClassName
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
// Java安全相关,权限控制
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () ->
doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
}
else {
return doResolveBeanClass(mbd, typesToMatch);
}
}
catch (PrivilegedActionException pae) {
ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
}
catch (ClassNotFoundException ex) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
}
catch (LinkageError err) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
}
}
// org.springframework.beans.factory.support.AbstractBeanFactory#doResolveBeanClass
@Nullable
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
throws ClassNotFoundException {

// 这里会有两个classLoader
ClassLoader beanClassLoader = getBeanClassLoader(); // 当前AppClassLoader,固定的
ClassLoader dynamicLoader = beanClassLoader;
boolean freshResolve = false;

if (!ObjectUtils.isEmpty(typesToMatch)) { // 由上面的传参来看,typesToMatch永远都是空的
// When just doing type checks (i.e. not creating an actual instance yet),
// use the specified temporary class loader (e.g. in a weaving scenario).
ClassLoader tempClassLoader = getTempClassLoader(); // ConfigurableBeanFactory 临时 ClassLoader
if (tempClassLoader != null) {
dynamicLoader = tempClassLoader;
freshResolve = true;
if (tempClassLoader instanceof DecoratingClassLoader) {
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
for (Class<?> typeToMatch : typesToMatch) {
dcl.excludeClass(typeToMatch.getName());
}
}
}
}

// 获取String类型的beanClassName
String className = mbd.getBeanClassName();
if (className != null) {
Object evaluated = evaluateBeanDefinitionString(className, mbd);
if (!className.equals(evaluated)) {
// A dynamically resolved expression, supported as of 4.2...
if (evaluated instanceof Class) {
return (Class<?>) evaluated;
}
else if (evaluated instanceof String) {
className = (String) evaluated;
freshResolve = true;
}
else {
throw new IllegalStateException("Invalid class name expression result: " + evaluated);
}
}
if (freshResolve) {
// When resolving against a temporary class loader, exit early in order
// to avoid storing the resolved Class in the bean definition.
if (dynamicLoader != null) {
try {
return dynamicLoader.loadClass(className);
}
catch (ClassNotFoundException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
}
}
}
return ClassUtils.forName(className, dynamicLoader);
}
}

// Resolve regularly, caching the result in the BeanDefinition...
return mbd.resolveBeanClass(beanClassLoader); // 关键代码
}
// org.springframework.beans.factory.support.AbstractBeanDefinition#resolveBeanClass
@Nullable
public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {
String className = getBeanClassName(); // 获取class名
if (className == null) {
return null;
}
// 使用classLoader加载class
Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
this.beanClass = resolvedClass;
return resolvedClass;
}

2、总结

上面分析了一大顿,总体来说就是,AbstractBeanFactory#resolveBeanClass中将string类型的beanClass 通过当前线程Thread.currentThread().getContextClassLoader(),Class.forName来获取class对象,将beanClass变为Class类型对象。

这里有个小细节,ConfigurableBeanFactory接口有个setTempClassLoader方法可以设置临时的classLoader,就是上面我们分析的临时classLoader。

六、Spring Bean 实例化阶段

1、实例化前阶段

通常来说,Spring Bean 实例化前阶段 日常工作中基本很少会有人去用。

关键方法:InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法,InstantiationAwareBeanPostProcessor接口继承了BeanPostProcessor接口。

postProcessBeforeInstantiation会在Bean实例化前进行执行,这个操作会打破Spring Bean的注册。

事实上,spring5之后,InstantiationAwareBeanPostProcessor使用了default方法,spring5之前是用的抽象类InstantiationAwareBeanPostProcessorAdapter。

代码实例

class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

/**
* 实例化前执行
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (ObjectUtils.nullSafeEquals("superUser", beanName) && SuperUser.class.equals(beanClass)) {
// 把配置完成 superUser Bean 覆盖
return new SuperUser();
}
return null; // 保持 Spring IoC 容器的实例化操作
}

}
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 添加 BeanPostProcessor 实现 MyInstantiationAwareBeanPostProcessor
beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());

源码分析

postProcessBeforeInstantiation方法默认是返回null的,代表默认值,bean的实例化交给spring来处理。

// org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}

我们反推,找到调用postProcessBeforeInstantiation方法的地方:

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) { // 返回值不为null,直接返回
return result;
}
}
}
return null; // 最终没有找到实例化前的返回值,返回null。
}

我们继续反推,找到调用applyBeanPostProcessorsBeforeInstantiation方法的地方:

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) { // 调用
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}

继续往上找,AbstractAutowireCapableBeanFactory的createBean(String, RootBeanDefinition, Object[])方法中,调用了resolveBeforeInstantiation方法:
我们发现,如果依赖查找过程中,该指不为null的话,直接不需要创建bean,直接返回。

// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}

总结分析

也就是说InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法。
若返回为null,则返回默认的实例对象
若返回不为null,则此对象为最终返回的对象,也就是实例化了一个与配置文件中不同的新的对象。

2、Spring自身的Bean实例化阶段

源码分析

上面实例化前阶段我们分析了,如果InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法返回不为null就直接返回bean,那返回为null,就会继续执行下面的doCreateBean方法:

我们继续看AbstractAutowireCapableBeanFactory的createBean(String, RootBeanDefinition, Object[])方法:

try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) { // 不为null直接返回
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}

// bean的创建逻辑
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {

// Instantiate the bean.
BeanWrapper instanceWrapper = null; // 包装的对象
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {// 如果缓存中没有,就创建bean的实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// ... 下面的就是初始化的逻辑了
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName); // 处理bean的Class

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());
}

// jdk8支持的lambda写法,spring5之前是没有的
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}

if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}

// Shortcut when re-creating the same bean... 重复创建相同bean时。。。
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
// 减少重复,性能优化
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
// 通过构造器方式
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 传统instantiateBean方式
return instantiateBean(beanName, mbd);
}
}

// Candidate constructors for autowiring? 构造器注入
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}

// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}

// 简单用无参构造器实例化
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}

源码分析-简单用无参构造器实例化

假如说我们定义了这样一个bean,它实例化时,就会使用无参构造器实例化:

public class User {

private Long id;

private String name;

private City city;
// ... 略get set
<bean id="user" class="com.test.domain.User">
<property name="id" value="1"/>
<property name="name" value="张三"/>
<property name="city" value="HANGZHOU"/>
</bean>

通过上面的分析,我们知道bean的实例化分了三种,我们先分析简单的用无参构造器进行实例化的方式。

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#instantiateBean
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
// 返回普通的对象,属性都是没有赋值过的,都是默认值
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw); // 初始化wrapper对象,还没有进行属性的设置,和初始化
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}

以上代码的getInstantiationStrategy()会默认获取CglibSubclassingInstantiationStrategy的策略,而CglibSubclassingInstantiationStrategy继承了SimpleInstantiationStrategy,上面的代码调用instantiate,也就是调用了SimpleInstantiationStrategy中的instantiate方法:

// org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory)
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass(); // chass已经在加载阶段加载了
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else { // 查找构造方法
constructorToUse = clazz.getDeclaredConstructor();
}
// 减少重复,性能优化
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 实例化bean
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}

源码分析-通过构造器进行实例化

更多关于构造器注入,请移步以下文章中的 依赖注入-构造器注入:
​spring依赖查找、依赖注入深入学习及源码分析​​ 假如说我们定义了这样一个bean,通过构造器自动注入,它实例化时,就会使用构造器实例化:

public class UserHolder {

private final User user;

public UserHolder(User user) {
this.user = user;
}
// 略。。
<bean id="userHolder" class="com.test.domain.UserHolder" autowire="constructor" >
</bean>

其中,构造器实例化是一种特殊的实例化方式,我们继续分析源码:

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#autowireConstructor
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {

return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
// org.springframework.beans.factory.support.ConstructorResolver#autowireConstructor
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {

BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);

Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;

if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}

// 执行该逻辑
if (constructorToUse == null || argsToUse == null) {
// Take specified constructors, if any.
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) { // candidates 获取带参构造器
Class<?> beanClass = mbd.getBeanClass();
try {
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}

if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Constructor<?> uniqueCandidate = candidates[0]; // 唯一的一个构造器
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}

// Need to resolve the constructor. 自动注入规则是构造器注入的
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;

int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}

AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;

for (Constructor<?> candidate : candidates) {

int parameterCount = candidate.getParameterCount();

if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
if (parameterCount < minNrOfArgs) {
continue;
}

ArgumentsHolder argsHolder;
Class<?>[] paramTypes = candidate.getParameterTypes();
if (resolvedValues != null) {
try {
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
if (paramNames == null) {
// ParameterNameDiscoverer 有两种实现,一种是java8一种是非java8
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate); // 获取构造器的参数名称,user
}
}
// 该方法会执行依赖处理的逻辑,先按照类型在按照名称进行获取
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
else {
// Explicit arguments given -> arguments length must match exactly.
if (parameterCount != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}

int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}

if (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}

if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}

Assert.state(argsToUse != null, "Unresolved constructor arguments");
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}

总结分析

依赖查找的过程其实很复杂,基本按照以下逻辑进行依赖查找的:按类型找->通过限定符@Qualifier过滤->@Primary->@Priority->根据名称找(字段名称或者参数名称)。

依赖查找之所以类型的优先级最高,是因为在 DefaultListableBeanFactory#findAutowireCandidates 中:
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager()); candidateNames 是调用 lbf.getBeanNamesForType 获取的,也就是说是通过类型获取的Bean名称列表,通过名称列表遍历获取并获取Bean实例,遍历时会筛选 Qualifer :
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
然后返回结果 matchingBeans 也就是:
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
接下来会 matchingBeans 中筛选出唯一的一个 beanName,即determineAutowireCandidate方法的结果:
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
determineAutowireCandidate 方法中根据 primary -> priority -> resolvableDependencies.containsValue(beanInstance) -> matchesBeanName(candidateName, descriptor.getDependencyName());
matchesBeanName 中 就是通过名称或者别名来匹配。
所以,顺序为 type->qualifer-> primary -> priority -> resolvableDependencies.containsValue(beanInstance) -> beanName

简述以上Spring自身Bean实例化的过程:
想要生成一个 Bean,那么需要先根据其 Class 对象创建一个 Bean 的实例对象,然后进行一系列的初始化工作。在创建 Bean 的实例对象的过程中,传统的实例化方式(大多数情况)使用 InstantiationStrategy 这个接口来实现,获取默认构造器,然后通过它创建一个实例对象。还有一种方式就是需要通过构造器注入相关的依赖对象,首先会获取构造器中的参数对象(依赖注入,入口:DefaultListableBeanFactory#resolveDependency,前面已经分析过了),根据这些需要注入的依赖对象,通过指定的构造器创建一个实例对象。

3、实例化后阶段

Spring Bean实例化后阶段我们可以理解为Bean的赋值的一个判断,或赋值前置的一个操作。

关键方法:InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法,跟实例化前阶段的方法在同一个接口中。

代码实例

class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

/**
* 实例化后执行
*/
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (ObjectUtils.nullSafeEquals("user", beanName) && User.class.equals(bean.getClass())) {
User user = (User) bean;
user.setId(2L);
user.setName("李四");
// "user" 对象不允许属性赋值(填入)(xml、注解等配置的属性不生效了,属性被赋值为此处的属性值)
return false;
}
return true;
}
}

将MyInstantiationAwareBeanPostProcessor注册到IOC容器(同实例化前阶段)。

源码分析

// org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}

该方法返回true的话,bean上的属性应该被设置;false的话,bean的属性赋值就应该被跳过。

在上面Spring自身的Bean实例化阶段我们分析到,AbstractAutowireCapableBeanFactory的doCreateBean方法中,调用createBeanInstance来实例化Bean,我们继续看下面的代码:

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {

// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 上面分析的,Spring自身实例化Bean的过程,此时属性还没有被赋值
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}

// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 这里有一个MergedBeanDefinitionPostProcessor的回调,执行postProcessMergedBeanDefinition方法
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}

// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

// Initialize the bean instance.
Object exposedObject = bean;
try {
// 属性值的填入(关键方法)
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}

if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!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.");
}
}
}
}

// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}

return exposedObject;
}
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}

// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 返回false的话,直接return,后面的逻辑全不会执行
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}

// postProcessAfterInstantiation没有返回false的,会执行下面的逻辑
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}

boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}

if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}

总结分析

postProcessAfterInstantiation就是相当于判断bean的实例是否应该属性赋值,如果返回false就不会执行属性赋值的逻辑,返回true就会走属性赋值的逻辑。

所以,当返回false的时候,我们应该在postProcessAfterInstantiation方法中写自定义的逻辑进行组装,也就相当于一个拦截机制。


标签:生命周期,String,mbd,Spring,beanName,bean,Bean,new,null
From: https://blog.51cto.com/u_13540373/6023560

相关文章

  • SpringBoot 定时任务
    示例#ScheduledTaskService.javapackagecom.ln.myboot3.schedule;importorg.springframework.scheduling.annotation.Scheduled;importorg.springframework.ster......
  • SpringBoot 定时任务示例
    示例#ScheduledTaskService.javapackagecom.ln.myboot3.schedule;importorg.springframework.scheduling.annotation.Scheduled;importorg.springframework.ster......
  • 230125_50_SpringBoot入门
    SpringBoot实战:员工管理系统1.静态资源导入可以从百度网盘获取资源:链接:https://pan.baidu.com/s/1x-6U_NCNEhIXOq0CcvRW-g提取码:mg94复制这段内容后打开百度......
  • SpringMVC
    SpringMVCssm:mybatis+Spring+SpringMVCMVC三层架构SpringMVC+Vue+SpringBoot+SpringCloud+LinuxSSM=JavaWeb做项目Spring:IOC和AOPSpringMVC:SpringMVC......
  • springday5_数据层
    数据层解决方案SQL数据源持久化数据库NoSQLRedisMongo1.导入坐标2.添加配置ES......
  • SpringBoot 教程
    什么是SpringBootSpringBoot教程提供了SpringFramework的基本和高级概念。我们的SpringBoot教程面向初学者和专业人士。SpringBoot是一个Spring模块,为Spring框架提......
  • Spring万字详解DI相关内容,一文掌握DI配置与使用
    Spring往期回顾......
  • bean的实例化
    1.构造方法    ......
  • spring boot——请求与参数校验——重要概念——Lombok初步简介
                 常用注解下面介绍一下常用的几个注解:@Setter注解在类或字段,注解在类时为所有字段生成setter方法,注解在字段上时只为该字段......
  • Spring IOC
    SpringIOC主要是控制反转1publicclassA(){2System.out.println("a");3}4publicclassB(){5System.out.println("b");6}如果要在A中使用B,可以通......