目录
1、InstantiationAwareBeanPostProcessor :
2、martInstantiationAwareBeanPostProcessor 后置处理器:
3、SmartInstantiationAwareBeanPostProcessor后置处理器
4、InstantiationAwareBeanPostProcessor初始化后置处理器
3.2、spring 内置的实现 (主要作用是判断 bean是否需要被代理 ,需要被代理的类 就放入map中)
4.2、instantiateBean(beanName, mbd)使用默认无参构造器实例化对象
4.3、使用依赖注入的构造器实例化对象:autowireConstructor(beanName, mbd, ctors, args)
五、处理合并BeanDefinition与解决循环依赖后置处理器
5.1、第三调用后置处理器MergedBeanDefinitionPostProcessor
6.1、第五次调用后置处理器 :属性是否注入InstantiationAwareBeanPostProcessor
经过上一篇的BeanDefinition 生成过程后,已经得到实例化bean的相关的源信息,这一篇重点介绍spring bean的实例化的过程,也就是我们通常的创建对象,不过这样需要推断构造器,使用反射实例化对象。
此阶段主要包括: Spring Bean 实例化前阶段、Spring Bean 实例化阶段、Spring Bean 实例化后阶段等阶段。
一、这里涉及几个比较重要的后置处理器:
1、InstantiationAwareBeanPostProcessor :
- Spring Bean 实例化前阶段: 第一次调用后置处理器 postProcessBeforeInstantiation 方法 默认实现是判断是否需要代理放入map中
- Spring Bean 实例化后置阶段: 第五次调用后置处理器 postProcessAfterInstantiation方法 属性赋值(Populate)判断是否需要属性填充
- populateBean属性赋值 : 第六次调用后置处理器:postProcessPropertyValues 为bean填充属性包括依赖注入的属性
2、martInstantiationAwareBeanPostProcessor 后置处理器:
第二次调用后置处理器determineCandidateConstructors获取最优构造方法实例化对象
3、SmartInstantiationAwareBeanPostProcessor后置处理器
第四次调用后置处理器getEarlyBeanReference解决循环依赖的问题
4、InstantiationAwareBeanPostProcessor初始化后置处理器
- Spring Bean 初始化前阶段 postProcessBeforeInitialization
- Spring Bean 初始化后阶段:postProcessAfterInitialization
在实例化阶段主要涉及 1到3 后置处理器 如下图:
二、Bean实例化详细流程
相关入口:
- 根据类型获取Bean
org.springframework.context.support.AbstractApplicationContext.getBean(Class<T>)- 根据名字获取Bean
org.springframework.context.support.AbstractApplicationContext.getBean(String)- 实际获取Bean
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean- 根据给出的Bean获取真实Bean(可能是factoryBean)
org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance- 创建Bean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean- 实际创建Bean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean
下面是 的相关源码
AbstractApplicationContext.finishBeanFactoryInitialization()实例化bean入口方法
//创建Bean实例对象
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
//判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 校验和准备Bean中的方法覆盖
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
//如果Bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建Bean的代理对象
//TODO 第一次调用bean的后置处理器 主要判断bean需要被代理 bean一般都为空
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 {
//创建Bean的入口
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException ex) {
// A previously detected exception with proper bean creation context already...
throw ex;
}
catch (ImplicitlyAppearedSingletonException ex) {
// An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry...
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
三、Spring Bean 实例化前阶段
第一次调用后置处理器
非主流生命周期 -- Bean 实例化前阶段:InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
3.1、自己实现 (这个在开发过程几乎用不到)
自己实现后置处理器的postProcessBeforeInstantiation 方法替换把配置完成的 superUser bean覆盖。重新生成一个superUser 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">
<!-- <context:annotation-config/>-->
<!-- <context:component-scan base-package="org.acme" />-->
<!-- Root BeanDefinition 不需要合并,不存在 parent -->
<!-- 普通 beanDefinition GenericBeanDefinition -->
<!-- 经过合并后 GenericBeanDefinition 变成 RootBeanDefinition -->
<bean id="user" class="org.geekbang.thinking.in.spring.ioc.overview.domain.User">
<property name="id" value="1"/>
<property name="name" value="小马哥"/>
<property name="city" value="HANGZHOU"/>
<property name="workCities" value="BEIJING,HANGZHOU"/>
<property name="lifeCities">
<list>
<value>BEIJING</value>
<value>SHANGHAI</value>
</list>
</property>
<property name="configFileLocation" value="classpath:/META-INF/user-config.properties"/>
</bean>
<!-- 普通 beanDefinition GenericBeanDefinition -->
<!-- 合并后 GenericBeanDefinition 变成 RootBeanDefinition,并且覆盖 parent 相关配置-->
<!-- primary = true , 增加了一个 address 属性 -->
<bean id="superUser" class="org.geekbang.thinking.in.spring.ioc.overview.domain.SuperUser" parent="user"
primary="true">
<property name="address" value="杭州"/>
</bean>
</beans>
public class BeanInstantiationDemo {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 方法一:添加 BeanPostProcessor 实现 MyInstantiationAwareBeanPostProcessor
beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessorDome());
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
String location = "META-INF/dependency-lookup-context.xml";
Resource resource = new ClassPathResource(location);
// 指定字符编码 UTF-8
EncodedResource encodedResource = new EncodedResource(resource, "UTF-8");
beanDefinitionReader.loadBeanDefinitions(encodedResource);
// 通过 Bean Id 和类型进行依赖查找
User user = beanFactory.getBean("user", User.class);
System.out.println(user);
User superUser = beanFactory.getBean("superUser", User.class);
System.out.println(superUser);
}
/**
* 实现 后置处理器
*/
static class MyInstantiationAwareBeanPostProcessorDome 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;//这里表示什么都不变化
}
}
}
执行日志。我们可以看到 SuperUser 只是实例化了 ,什么属性都没有填充
User{id=1, name='小马哥', city=HANGZHOU, workCities=[BEIJING, HANGZHOU], lifeCities=[BEIJING, SHANGHAI], configFileLocation=class path resource [META-INF/user-config.properties], company=null, context=null, contextAsText='null', beanName='user'}
SuperUser{address='null'} User{id=null, name='null', city=null, workCities=null, lifeCities=null, configFileLocation=null, company=null, context=null, contextAsText='null', beanName='null'}
3.2、spring 内置的实现 (主要作用是判断 bean是否需要被代理 ,需要被代理的类 就放入map中)
代码位置:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation(beanName, mbdToUse)
@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.
//TODO mbd.isSynthetic() 表示是否合成类
// hasInstantiationAwareBeanPostProcessors() 判断系统是否有 InstantiationAwareBeanPostProcessors
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;
}
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) {
return result;
}
}
}
return null;
}
主要实现类就一个AbstractAutoProxyCreator#postProcessBeforeInstantiation
主要作用是判断 bean是否需要被代理 ,需要被代理的类 就放入map中
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
//advisedBeans 不需要被代理的对象
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
四、Spring Bean 实例化阶段
实例化阶段主要是 根据后置处理器 推断出 实例化bean的最优构造方法,实例化对象。
第二次调用bean的后置处理器:推断实例化构造方法---》SmartInstantiationAwareBeanPostProcessor #determineCandidateConstructors
路径:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance(beanName, mbd, args)
接口:SmartInstantiationAwareBeanPostProcessor #determineCandidateConstructors(Class<?> beanClass, String beanName)
实现类:AutowiredAnnotationBeanPostProcessor #determineCandidateConstructors
这个后置处理器 需要实现 SmartInstantiationAwareBeanPostProcessor接口
实例化方式:
1、使用默认无参构造器:instantiateBean(beanName, mbd)
实例化策略 - InstantiationStrategy--- instantiationStrategy = new CglibSubclassingInstantiationStrategy()---- SimpleInstantiationStrategy
2、使用依赖注入的构造器:autowireConstructor(beanName, mbd, ctors, args)
createBeanInstance 代码实现
//创建Bean的实例对象
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
//检查确认Bean是可实例化的
Class<?> beanClass = resolveBeanClass(mbd, beanName);
//使用工厂方法对Bean进行实例化
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());
}
//todo 这个程序员自己提供创建对象的方法
// 这里使用自己提供的 方法实例化对象, 不需要spring推断构造方法区实例化bean
// genericBeanDefinition.setInstanceSupplier(() -> new IndexService(beanFactory.getBean(OrderSevice.class)));
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
//todo 这个程序员自己提供创建对象的工厂方法 factory-method
if (mbd.getFactoryMethodName() != null) {
//调用工厂方法实例化
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
//TODO 下面是重点 开始创建bean 使用容器的自动装配方法进行实例化
//表示创建对象的构造方法没有被解析过
boolean resolved = false;
//是否需要自动注入
boolean autowireNecessary = false;
//args 一般都为空
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
//Todo 下面很重要 如果不为空 表示这个class 方法被解析过了 表示已经找到了创建对象的方式
// 一般在原型模式中 使用 快捷方式,不需要再次解析构造方法
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
//配置了自动装配属性,使用容器的自动装配实例化
//容器的自动装配是根据参数类型匹配Bean的构造方法
return autowireConstructor(beanName, mbd, null, null);
}
else {
//使用默认的无参构造方法实例化
return instantiateBean(beanName, mbd);
}
}
// Need to determine the constructor...
//TODO 第二次调用后置处理器推断构造方法 下面是单例对象的 使用Bean的构造方法进行实例化
//找到 class 构造方法 特殊的算法
/* TODO spring 通过构造方法实例化 bean的原理
实例化这个对象---首先要推断构造方法
这个分两种类型
1、手动注入
会在后置处理器中 找到实现 SmartInstantiationAwareBeanPostProcessor接口的类型
AutowiredAnnotationBeanPostProcessor类中的determineCandidateConstructors 方法来推断出
合适的构造方法创建对象
1.1、只有一个无参构造方法 ctors为 null 使用默认无参构造方法
1.2 如果有多个构造方法 ctors为 null 使用默认无参构造方法
1.3 如果只有一个有参构造方法 ctors不为null 因为只有一个有参数的 只能用这个了
1.4、多个构造方法 且只有一个构造方法加了@Autowired(required = true) 用这个构造方法来创建对象
1.5、多个构造方法 且多个构造方法加了@Autowired(required = true) spring ioc容器报错
1.6、多个构造方法 且多个构造方法加了@Autowired(required = false) 就把构造方法都加到集合中 第二次推断
2、自动注入 --通过构造方法自动注入
2.1、如果有多个构造方法 找出最优的构造器 参数最多的 为最优的
*/
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || //这个表示自动装配
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//使用容器的自动装配特性,调用匹配的构造方法实例化
//使用推断出来的构造方法找到一个可以用的 实例化bean
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
//使用默认的无参构造方法实例化
return instantiateBean(beanName, mbd);
}
4.1、第二次调用后置处理器推断构造方法
接口:SmartInstantiationAwareBeanPostProcessor #determineCandidateConstructors(Class<?> beanClass, String beanName)
实现类:AutowiredAnnotationBeanPostProcessor #determineCandidateConstructors
其中推断构造器的规则
这个分两种类型
1、手动注入
合适的构造方法创建对象
1.1、只有一个无参构造方法 ctors为 null 使用默认无参构造方法
1.2 如果有多个构造方法 ctors为 null 使用默认无参构造方法
1.3 如果只有一个有参构造方法 ctors不为null 因为只有一个有参数的 只能用这个了
1.4、多个构造方法 且只有一个构造方法加了@Autowired(required = true) 用这个构造方法来创建对象
1.5、多个构造方法 且多个构造方法加了@Autowired(required = true) spring ioc容器报错
1.6、多个构造方法 且多个构造方法加了@Autowired(required = false) 就把构造方法都加到集合中 第二次推断2、自动注入 --通过构造方法自动注入
2.1、如果有多个构造方法 找出最优的构造器 参数最多的为最优的2.2、多个构造方法 且只有一个构造方法加了@Autowired(required = true) 用这个构造方法来创建对象
2.3、多个构造方法 且多个构造方法加了@Autowired(required = true) spring ioc容器报错
代码实现:
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// AutowiredAnnotationBeanPostProcessor 这个后置处理 实现了 SmartInstantiationAwareBeanPostProcessor
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
//TODO 推断构造器 AutowiredAnnotationBeanPostProcessor
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
}
return null;
}
实现类:AutowiredAnnotationBeanPostProcessor #determineCandidateConstructors
//TODO 为自动依赖注入装配Bean选择合适的构造方法
@Override
@Nullable
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
throws BeanCreationException {
// Let's check for lookup methods here..
if (!this.lookupMethodsChecked.contains(beanName)) {
try {
ReflectionUtils.doWithMethods(beanClass, method -> {
Lookup lookup = method.getAnnotation(Lookup.class);
if (lookup != null) {
Assert.state(beanFactory != null, "No BeanFactory available");
LookupOverride override = new LookupOverride(method, lookup.value());
try {
RootBeanDefinition mbd = (RootBeanDefinition) beanFactory.getMergedBeanDefinition(beanName);
mbd.getMethodOverrides().addOverride(override);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(beanName,
"Cannot apply @Lookup to beans without corresponding bean definition");
}
}
});
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
}
this.lookupMethodsChecked.add(beanName);
}
//首先从容器的缓存中查找是否有指定Bean的构造方法
// Quick check on the concurrent map first, with minimal locking.
// candidateConstructorsCache 这个 class的构造方法的map
Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
// Fully synchronized resolution now...
//线程同步以确保容器中数据一致性
synchronized (this.candidateConstructorsCache) {
candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
Constructor<?>[] rawCandidates;
try {
//通过JDK反射机制,获取指定类的中所有声明的构造方法
rawCandidates = beanClass.getDeclaredConstructors();
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
//存放候选中合格的构造方法的集合
List<Constructor<?>> candidates = new ArrayList<Constructor<?>>(rawCandidates.length);
//autowire注解中required属性指定的构造方法
Constructor<?> requiredConstructor = null;
//默认的构造方法
Constructor<?> defaultConstructor = null;
//主构造方法 把推断的主要构造方法委托给 kotlin 非kotlin的类永远为空
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
//遍历所有的构造方法,检查是否添加了autowire注解,以及是否指定了required属性
for (Constructor<?> candidate : rawCandidates) {
//判断是不是一个合成的类 一般不会进来
if (!candidate.isSynthetic()) {
nonSyntheticConstructors++;
}
else if (primaryConstructor != null) {
continue;
}
//获取指定类中所有关于autowire的注解(Annotation)
AnnotationAttributes ann = findAutowiredAnnotation(candidate);
//如果指定类中没有antowire的注解
if (ann == null) {
Class<?> userClass = ClassUtils.getUserClass(beanClass);
if (userClass != beanClass) {
try {
Constructor<?> superCtor =
userClass.getDeclaredConstructor(candidate.getParameterTypes());
ann = findAutowiredAnnotation(superCtor);
}
catch (NoSuchMethodException ex) {
// Simply proceed, no equivalent superclass constructor found...
}
}
}
//如果指定类中有关于antowire的注解
if (ann != null) {
//如果antowire注解中指定了required属性
if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
//获取autowire注解中required属性值
boolean required = determineRequiredStatus(ann);
//如果获取到autowire注解中required的属性值
if (required) {
//如果候选构造方法集合不为空
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
//当前的构造方法就是required属性所配置的构造方法
requiredConstructor = candidate;
}
//将当前的构造方法添加到哦啊候选构造方法集合中
candidates.add(candidate);
}
//如果autowire注解的参数列表为空
else if (candidate.getParameterCount() == 0) {
defaultConstructor = candidate;
}
}
//如果候选构造方法集合不为空
if (!candidates.isEmpty()) {
// Add default constructor to list of optional constructors, as fallback.
//如果所有的构造方法都没有配置required属性,且有默认构造方法
if (requiredConstructor == null) {
if (defaultConstructor != null) {
//将默认构造方法添加到候选构造方法列表
candidates.add(defaultConstructor);
}
else if (candidates.size() == 1 && logger.isWarnEnabled()) {
logger.warn("Inconsistent constructor declaration on bean with name '" + beanName +
"': single autowire-marked constructor flagged as optional - " +
"this constructor is effectively required since there is no " +
"default constructor to fall back to: " + candidates.get(0));
}
}
//将候选构造方法集合转换为数组
candidateConstructors = candidates.toArray(new Constructor<?>[candidates.size()]);
}
//TODO 这里是判断构造方法 是否只有一个有参构造 如果一个有参构造则 为有效的构造方法
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
//下面两个都不成立 primaryConstructor != null
else if (nonSyntheticConstructors == 2 && primaryConstructor != null && defaultConstructor != null) {
candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
}
else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
candidateConstructors = new Constructor<?>[] {primaryConstructor};
}
else {
//如果候选构造方法集合为空,则创建一个空的数组
candidateConstructors = new Constructor<?>[0];
}
//将类的候选构造方法集合存放到容器的缓存中
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
//返回指定类的候选构造方法数组,如果没有返回null
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
4.2、instantiateBean(beanName, mbd)使用默认无参构造器实例化对象
当推断出来使用默认无参构造
//使用默认的无参构造方法实例化Bean对象
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
//获取系统的安全管理接口,JDK标准的安全管理API
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);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
4.3、使用依赖注入的构造器实例化对象:autowireConstructor(beanName, mbd, ctors, args)
使用条件:推断处理的 构造器方法不为null或者开启自动装配或者 使用指定入参的构造方法
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || //这个表示自动装配
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//使用容器的自动装配特性,调用匹配的构造方法实例化
//使用推断出来的构造方法找到一个可以用的 实例化bean
return autowireConstructor(beanName, mbd, ctors, args);
}
具有实现:ConstructorResolver#autowireConstructor 这里会再次推断构造方法实例化对象。
public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable final Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
//TODO 最后被确认使用的 构造方法
Constructor<?> constructorToUse = null;
//这里面存放的 构造方法的参数
ArgumentsHolder argsHolderToUse = null;
//最终确定的参数
Object[] argsToUse = null;
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
//判断当前类 有没有解析构造方法 单例一般都为false
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);
}
}
//这个单例模式的处理
if (constructorToUse == null) {
// Need to resolve the constructor.
//判断是否需要自动注入
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
//构造方法参数个数的最小值
int minNrOfArgs;
//这个数根据传入参数做判断
if (explicitArgs != null) {
//表示实例spring 那个构造方法最少要多少
minNrOfArgs = explicitArgs.length;
}
else {
//获取构造方法的 参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
//
resolvedValues = new ConstructorArgumentValues();
//得到构造方法参数个数的最小值
//todo 这个一般为0 除非在实例化的时候
/*
GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) beanFactory.getBeanDefinition("indexService");
genericBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue(beanFactory.getBean(UserServiceTest.class));
*/
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// Take specified constructors, if any.
//TODO 开始处理构造方法
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
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);
}
}
//todo 对构造方法进行排序
// 排序规则 1、public 2、参数个数
AutowireUtils.sortConstructors(candidates);
//差异值
int minTypeDiffWeight = Integer.MAX_VALUE;
//模糊不清的构造方法
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
for (Constructor<?> candidate : candidates) {
Class<?>[] paramTypes = candidate.getParameterTypes();
// TODO 最终使用的 如果找到一个就直接退出了 最重要的条件 argsToUse.length > paramTypes.length
if (constructorToUse != null && argsToUse.length > paramTypes.length) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
if (paramTypes.length < minNrOfArgs) {
continue;
}
//最后要使用的参数
ArgumentsHolder argsHolder;
if (resolvedValues != null) {
//得到当前构造方法的参数名字
try {
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
if (paramNames == null) {
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
}
//TODO
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring);
}
catch (UnsatisfiedDependencyException ex) {
if (this.beanFactory.logger.isTraceEnabled()) {
this.beanFactory.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 (paramTypes.length != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
//计算差异值 -1024
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)");
}
//mbd.isLenientConstructorResolution() 宽松模式
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) {
//todo
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
try {
final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
Object beanInstance;
if (System.getSecurityManager() != null) {
final Constructor<?> ctorToUse = constructorToUse;
final Object[] argumentsToUse = argsToUse;
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
beanFactory.getAccessControlContext());
}
else {
beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
bw.setBeanInstance(beanInstance);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via constructor failed", ex);
}
}
五、处理合并BeanDefinition与解决循环依赖后置处理器
实例化后会第三和第四调用后置处理器
5.1、第三调用后置处理器MergedBeanDefinitionPostProcessor
这里主要解决 处理合并BeanDefinition的问题
入口:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)
接口:这个后置处理器 需要实现 MergedBeanDefinitionPostProcessor 接口中的postProcessMergedBeanDefinition方法
1、合并相关介绍:
为什么会提前合并 下面代码
通过类型找到名字---返回一个BeanFactoryPostProcessor的集合--完成了合并
不能用原始的BeanDefinition 去比较 必须合并
代码流程 ---AbstractApplicationContext.invokeBeanFactoryPostProcessors(beanFactory);-->>PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());-->DefaultListableBeanFactory.getBeanNamesForType(@Nullable Class<?> type) -->RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
/通过类型找到名字---返回一个BeanFactoryPostProcessor的集合--完成了合并
//返回一个BeanDefinition 后置工厂的名字的集合--通过名字实例化BeanFactoryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
但是在实例化bean的时候会重新在去 合并bd 会把缓存中的合并后的BeanDefinition删除在重新合并
AbstractAutowireCapableBeanFactory applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);调用后置处理的源码
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
1.1 、实现类:AutowiredAnnotationBeanPostProcessor
- findAutowiredMetadata----找出所有需要完成注入的“点”-----@Autowired @Value注解方法或者属性---为什么不需要构造方法
- checkConfigMembers----injectedElements 做了一个复制
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
//
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
1.2、实现类:CommonAnnotationBeanPostProcessor
- 调用父类的方法,查找所有的生命周期回调方法---初始化和销毁
- findResourceMetadata----找出所有需要完成注入的“点”-----@Resource注解
- checkConfigMembers----injectedElements 做了一个复制
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
两者使用的bean的后置处理器不一样的。
5.2、第四次调用后置处理器 解决循环依赖提前暴露一个工厂
这个工厂是一个lambda表达式,在出现循环依赖的时候执行
重点 解决循环依赖 提前暴露的是一个工厂 而不是一个对象;
地址:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getEarlyBeanReference(beanName, mbd, bean)
//向容器中缓存单例模式的Bean对象,以防循环引用
//TODO 判断是否允许循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用
//TODO 第四调用后置处理器
// 重点 解决循环依赖 提前暴露的是一个工厂 而不是一个对象
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
接口: SmartInstantiationAwareBeanPostProcessor# getEarlyBeanReference
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
实现类:AbstractAutoProxyCreator #getEarlyBeanReference
下面是添加到二级缓存中
@Override
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
this.earlyProxyReferences.add(cacheKey);
}
return wrapIfNecessary(bean, beanName, cacheKey);
}
六、spring bean实例化后置阶段
这个阶段主要判断当前实例化的bean是否需要属性注入
6.1、第五次调用后置处理器 :属性是否注入InstantiationAwareBeanPostProcessor
路径:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean(beanName, mbd, instanceWrapper)
//todo 第五次---属性是否注入InstantiationAwareBeanPostProcessor
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
接口:InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)
所有spring内置的实现类都为true
6.2、测试实例
我们当创建use bean的时候放回 false。这样这个bean就不会填充任何属性了。
/**
* Bean 实例化生命周期示例
*
* @Author: dukun0210
* @Date: 2021/2/17 19:23
*/
public class BeanInstantiationDemo {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 方法一:添加 BeanPostProcessor 实现 MyInstantiationAwareBeanPostProcessor
beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessorDome());
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
String location = "META-INF/dependency-lookup-context.xml";
Resource resource = new ClassPathResource(location);
// 指定字符编码 UTF-8
EncodedResource encodedResource = new EncodedResource(resource, "UTF-8");
beanDefinitionReader.loadBeanDefinitions(encodedResource);
// 通过 Bean Id 和类型进行依赖查找
User user = beanFactory.getBean("user", User.class);
System.out.println(user);
User superUser = beanFactory.getBean("superUser", User.class);
System.out.println(superUser);
}
/**
* 实现 后置处理器
*/
static class MyInstantiationAwareBeanPostProcessorDome 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;//这里表示什么都不变化
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if(ObjectUtils.nullSafeEquals("superUser",beanName) && SuperUser.class.equals(beanClass)){
//如果是 user 对象不允许属性的赋值
return false;
}
return true;//这里表示什么都不变化
}
}
}
总结: