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

  • Post author:
  • Post category:其他




写在前面


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方法中写自定义的逻辑进行组装,也就相当于一个拦截机制。



版权声明:本文为A_art_xiang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。