Spring源码之IOC
2. IOC
核心概念:
- 控制反转
- 依赖注入
本节主要针对 BeanFactory 分析
2.1 测试样例
分析源码之前,需要有测试用例。在spring-context
项目中,依次新建:
org.springframework.demo.Dog.java
org.springframework.demo.DogTests.java
resources/org/springframework/demo/demo.xml
package org.springframework.demo;
public class Dog {
private String name;
private int age;
public Dog() {
}
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
public void sayHello() {
System.out.println("大家好, 我叫" + getName() + ", 我今年" + getAge() + "岁了");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<bean id="dog" class="org.springframework.demo.Dog">
<property name="name" value="Jack"/>
<property name="age" value="12"/>
</bean>
</beans>
package org.springframework.demo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class DogTests {
@Test
public void dogBean() {
XmlBeanFactory xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("org/springframework/demo/demo.xml"));
Dog dog = xmlBeanFactory.getBean("dog", Dog.class);
dog.sayHello();
}
}
2.2 从缓存中获取bean实例
- Spring Bean的作用域有:
- prototype
- singleton 本专栏主要针对 singleton 分析
- request
- session
- global session
- 针对单例bean,IOC会缓存bean的实例信息,在doGetBean方法中有:
// 从缓存中获取bean实例
Object sharedInstance = getSingleton(beanName);
- 单例bean的实例信息被缓存在了:
// 缓存bean的实例信息
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
- 获取单例bean实例的部分代码(涉及循环依赖部分后文分析,初学者不要过度解读每一行代码):
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 从缓存中获取实例
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 省略部分代码。。。
}
return singletonObject;
}
- 总结:
- 针对单例bean,IOC先从缓存中获取该bean的实例,即从ConcurrentHashMap中获取。
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
这里涉及到FactoryBean相关知识,放到后续章节分析。
2.3 实例化bean的准备工作
接上文,Spring 首先尝试从缓存中获取bean的实例,若未能获取到,则创建新的bean的实例:
// Create bean instance.
// 创建bean实例
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
方法大体分为四个步骤,内部逻辑十分复杂,但是需要现有整体上的了解:
- getSingleton 获取单例bean实例
- createBean 创建bean实例
- catch 异常处理
- getObjectForBeanInstance(涉及FactoryBean,后续分析)
2.3.1 getSingleton
抛开创建bean实例来看,该方法主要处理创建bean的前置、后置、缓存等工作。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
// 加锁
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 在单例创建之前回调。
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 创建bean实例
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
// 在此期间是否隐式地出现了单例对象——>如果是,则继续处理它,因为异常指示了该状态。
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 在单例创建后回调。
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 缓存bean实例
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
- 前置回调 --> beforeSingletonCreation
- 创建bean实例 --> singletonFactory.getObject(); (代码太多,本小节不分析)
- 异常处理
- 后置回调 --> afterSingletonCreation
- 缓存实例 --> addSingleton
2.3.1.1 beforeSingletonCreation 前置处理
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
- 重要变量:
- 当前在创建检查中排除的bean的名称:
inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
- 标记bean是否正在创建中:
singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
- 当前在创建检查中排除的bean的名称:
- 逻辑:检查循环依赖,如果当前bean已经被标记为正在创建中,则抛出BeanCurrentlyInCreationException
2.3.1.2 afterSingletonCreation 后置处理
protected void afterSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
- 逻辑:与 beforeSingletonCreation 相反,因为bean已经创建完成,需要从 singletonsCurrentlyInCreation 移除
2.3.1.3 addSingleton 缓存bean实例
protected void addSingleton(String beanName, Object singletonObject) {
// 加锁
synchronized (this.singletonObjects) {
// 单例对象的缓存:从bean名称到bean实例。
this.singletonObjects.put(beanName, singletonObject);
// 单例工厂的缓存:从bean名到ObjectFactory。
this.singletonFactories.remove(beanName);
// 早期单例对象的缓存:从bean名称到bean实例。
this.earlySingletonObjects.remove(beanName);
// 一组已注册的单例,包含按注册顺序排列的bean名称。
this.registeredSingletons.add(beanName);
}
}
- 变量定义:
- private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
- private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
- private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
- private final Set registeredSingletons = new LinkedHashSet<>(256);
- 主要逻辑
- 将创建的Bean实例加入到 ConcurrentHashMap 中
- 如果刚开始看Spring源码,只需要理解 singletonObjects 即可。
2.3.2 createBean
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.
// 确保此时实际解析了bean类,并在无法存储在共享合并bean定义中的动态解析类的情况下克隆bean定义。
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
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.
// 让BeanPostProcessors有机会返回一个代理而不是目标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.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);
}
}
- 主要方法与变量:
- RootBeanDefinition Bean定义
- resolveBeanClass 解析BeanClass
- prepareMethodOverrides 准备方法覆盖。
- resolveBeforeInstantiation 让BeanPostProcessors有机会返回一个代理而不是目标bean实例。
- doCreateBean 真正开始创建bean实例
- 异常处理
- 逻辑:该方法依然是做创建Bean的准备工作
- resolveBeforeInstantiation涉及到AOP相关,放到后续小节分析,下面我们简单介绍下RootBeanDefinition、和prepareMethodOverrides
2.3.1 RootBeanDefinition 简介
关于 RootBeanDefinition 前文已经出现过,为了快速入门,并没有对其做过多介绍,这里我们简单了解一下:
- 将Bean的定义信息转化为Spring的内部表示。
- 间接实现了 BeanDefinition 接口,BeanDefinition 描述bean实例,该实例具有属性值、构造函数参数值和具体实现提供的进一步信息。
2.3.2 prepareMethodOverrides
**注意:这里的 method overrides 指方法注入。**该部分对应的源码比较简单,掌握其基本使用,应该都能读懂。下面演示一下lookup-method、replace-method的使用:
- 新建 BaseTests,为了方便测试,需要一个测试基类。
- lookup-method 依次新建
- org.springframework.demo.method.lookup.Car
- org.springframework.demo.method.lookup.Taxi
- org.springframework.demo.method.lookup.LookUpTests
- replace-method 依次新建
- org.springframework.demo.method.replace.OriginalDog
- org.springframework.demo.method.replace.ReplaceDog
- org.springframework.demo.method.replace.ReplaceTests
- 代码
-- for BaseTests
package org.springframework.demo;
import org.junit.jupiter.api.BeforeAll;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class BaseTests {
public static XmlBeanFactory xmlBeanFactory;
@BeforeAll
public static void beforeTest() {
xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("org/springframework/demo/demo.xml"));
}
}
-- for lookup-method
package org.springframework.demo.method.lookup;
public abstract class Car {
// 用于lookup-method注入
public abstract Taxi createTaxi();
private Taxi taxi;
public Taxi getTaxi() {
return taxi;
}
//setter注入
public void setTaxi(Taxi taxi) {
this.taxi = taxi;
}
}
package org.springframework.demo.method.lookup;
public class Taxi {
public void say() {
System.out.println("I am a Taxi...");
}
}
package org.springframework.demo.method.lookup;
import org.junit.jupiter.api.Test;
import org.springframework.demo.BaseTests;
public class LookUpTests extends BaseTests {
@Test
public void test(){
// 测试lookup-method注入
Car car1 = xmlBeanFactory.getBean("car", Car.class);
Car car2 = xmlBeanFactory.getBean("car", Car.class);
System.out.println("Car:singleton,所以animal1==animal2应该为" + (car1 == car2));
Taxi dog1 = car1.getTaxi();
Taxi dog2 = car2.getTaxi();
System.out.println("Taxi:prototype,Car:singleton,未使用lookup-method注入所以dog1==dog2应该为" + (dog1 == dog2));
//注意:这里是通过createTaxi()方法获取
Taxi taxi3 = car1.createTaxi();
Taxi taxi4 = car2.createTaxi();
System.out.println("Taxi:prototype,Car:singleton,使用了lookup-method注入所以dog3==dog4应该为" + (taxi3 == taxi4));
}
}
<!-- ====================lookup-method属性注入==================== -->
<bean id="car" class="org.springframework.demo.method.lookup.Car">
<!--注意:下面这句配置和lookup-method注入没有关系,我们只是为了出于演示和说明配置该bean-->
<property name="taxi" ref="taxi"/>
<!--lookup-method注入-->
<lookup-method name="createTaxi" bean="taxi"/>
</bean>
<bean id="taxi" class="org.springframework.demo.method.lookup.Taxi" scope="prototype"/>
-- for replace-method
package org.springframework.demo.method.replace;
public class OriginalDog {
public void sayHello() {
System.out.println("Hello,I am a black dog...");
}
public void sayHello(String name) {
System.out.println("Hello,I am a black dog, my name is " + name);
}
}
package org.springframework.demo.method.replace;
import org.springframework.beans.factory.support.MethodReplacer;
import java.lang.reflect.Method;
import java.util.Arrays;
public class ReplaceDog implements MethodReplacer {
@Override
public Object reimplement(Object obj, Method method, Object[] args) throws Throwable {
System.out.println("Hello, I am a white dog...");
Arrays.stream(args).forEach(str -> System.out.println("参数:" + str));
return obj;
}
}
package org.springframework.demo.method.replace;
import org.junit.jupiter.api.Test;
import org.springframework.demo.BaseTests;
public class ReplaceTests extends BaseTests {
@Test
public void test() {
// 测试replace-method注入
OriginalDog originalDog = xmlBeanFactory.getBean("originalDogReplaceMethod", OriginalDog.class);
originalDog.sayHello("输出结果已经被替换了。。。");
}
}
<!-- ====================replace-method属性注入==================== -->
<bean id="dogReplaceMethod" class="org.springframework.demo.method.replace.ReplaceDog"/>
<bean id="originalDogReplaceMethod" class="org.springframework.demo.method.replace.OriginalDog">
<replaced-method name="sayHello" replacer="dogReplaceMethod">
<arg-type match="java.lang.String"></arg-type>
</replaced-method>
</bean>
2.4 实例化bean
经过了前面的一系列准备,接下来进入IOC的核心方法doCreateBean。中间涉及较多的知识点,先来了解一下doCreateBean的主要逻辑。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
// 实例化bean。
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
// 允许后处理器修改合并的bean定义。
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
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.
// 主动缓存单例,以便能够解析循环引用,即使是在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.
// 初始化bean实例。
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 " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
// 将单例bean注册到disposableBeans(LinkedHashMap)中,以方面容器关闭时回调对应bean的销毁方法
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
- 主要逻辑:
- 创建bean的实例
- 允许后处理器修改合并的bean定义
- 主动缓存单例,以便能够解析循环引用
- 初始化bean实例
- 异常处理
- 将单例bean注册到disposableBeans(LinkedHashMap)中,以方面容器关闭时回调对应bean的销毁方法
- 返回bean的实例
- 重点分析:
- 创建bean的实例(控制反转)
- 初始化bean实例(依赖注入)
2.4.1 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);
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());
}
// Supplier 实例化
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 {
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的方式:
- Supplier
- 工厂方法:
- 静态工厂
- 实例工厂
- 构造函数:
- 有参构造函数
- 无参构造函数
- 快照实例化,该方式有些特殊。例如针对某个单例bean,创建完之后销毁,Spring依然会保留其解析快照,节约下次解析开销
2.4.1.1 Supplier
Supplier 接口是一个函数式接口,下面演示一下使用方式:
@Test
public void SupplierTest() {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext("org/springframework/demo/demo.xml");
context.registerBean("dog", Dog.class, new Supplier<Dog>() {
@Override
public Dog get() {
return new Dog();
}
});
context.getBean("dog", Dog.class).sayHello();
}
再来看一下Supplier接口的定义:
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
通过get方法返回bean的实例。这种实例化方式源码很简单,不多赘述。
2.4.1.2 静态工厂
该方式源码比较简单,只演示一下其使用方式:
package org.springframework.demo.factory;
import org.springframework.demo.Dog;
public class DogStaticFactory {
// 静态工厂方法
public static Dog newInstance(String name, int age) {
// 返回需要的Bean实例
return new Dog(name, age);
}
}
<!-- 静态工厂方法实例化 -->
<bean id="dog" class="org.springframework.demo.factory.DogStaticFactory" factory-method="newInstance">
<!-- 指定构造器参数 index对应构造器中参数的位置 -->
<constructor-arg index="0" value="小明"/>
<constructor-arg index="1" value="3"/>
</bean>
2.4.1.3 实例工厂
该方式源码比较简单,只演示一下其使用方式:
package org.springframework.demo.factory;
import org.springframework.demo.Dog;
public class DogFactory {
public Dog newInstance(String name, int age) {
return new Dog(name, age);
}
}
<!-- 实例工厂方法实例化 -->
<bean id="dogFactory" class="org.springframework.demo.factory.DogFactory"/>
<!-- 不能指定class属性,此时必须使用factory-bean属性来指定工厂Bean,factory-method属性指定实例化Bean的方法 -->
<bean id="dog" factory-bean="dogFactory" factory-method="newInstance">
<constructor-arg index="0" value="小明"/>
<constructor-arg index="1" value="3"/>
</bean>
2.4.1.4 有参构造函数
先来看一下使用有参构造函数的条件:
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null
|| mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR
|| mbd.hasConstructorArgumentValues()
|| !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
- determineConstructorsFromBeanPostProcessors 解析的构造函数不为空
- mbd.getResolvedAutowireMode 解析自动装配类型为构造函数
- mbd.hasConstructorArgumentValues 通过配置文件指定了构造函数参数
- !ObjectUtils.isEmpty(args) 获取bean的时候显示指定了构造函数参数
- 有参构造函数实例化的难点在于对构造函数的解析,代码极为繁杂,本文不展开分析
2.4.1.5 无参构造函数
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
getAccessControlContext());
}
else {
// 获取实例化策略,并实例化bean
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
2.4.2 无参实例化策略详解
上文提到了IOC实例化bean的几种策略,接下来的小节,重点分析无参、有参两种实例化策略。因为无参策略较为简单,所以先分析该策略。
入口代码:
// 获取实例化策略,并实例化bean
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
2.4.2.1 getInstantiationStrategy 获取实例化策略
/** Strategy for creating bean instances. 创建 bean 实例的策略。*/
private InstantiationStrategy instantiationStrategy;
/**
* Set the instantiation strategy to use for creating bean instances.
* Default is CglibSubclassingInstantiationStrategy.
* 设置用于创建 bean 实例的实例化策略。 默认为 CglibSubclassingInstantiationStrategy。
* @see CglibSubclassingInstantiationStrategy
*/
public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) {
this.instantiationStrategy = instantiationStrategy;
}
/**
* Return the instantiation strategy to use for creating bean instances.
* 返回用于创建 bean 实例的实例化策略
*/
protected InstantiationStrategy getInstantiationStrategy() {
return this.instantiationStrategy;
}
从代码中可以看到,IOC通过InstantiationStrategy接口来管理实例化策略,并且默认为CglibSubclassingInstantiationStrategy。但是IOC容器并没有显示的调用setInstantiationStrategy设置实例化策略,而是通过AbstractAutowireCapableBeanFactory的构造方法来创建实例化策略。
public AbstractAutowireCapableBeanFactory() {
super();
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
if (NativeDetector.inNativeImage()) {
this.instantiationStrategy = new SimpleInstantiationStrategy();
}
else {
// 实例化 CglibSubclassingInstantiationStrategy
this.instantiationStrategy = new CglibSubclassingInstantiationStrategy();
}
}
2.4.2.2 实例化策略概览
上一步拿到实例化策略后,就可以实例化bean了。
@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();
// 接口不能被实例化
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);
}
}
}
// 实例化
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
// 存在方法注入,必须使用 CGLIB
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
无方法注入,使用反射;否则,必须使用CGLIB
2.4.2.3 反射
- 获取构造方法
- constructorToUse = clazz.getDeclaredConstructor(); 通过Class类的getDeclaredConstructor()方法获取构造函数。因为这里是无参策略,所以无需传递任何参数。获取到构造方法后,再将其缓存到resolvedConstructorOrFactoryMethod中,方便下次使用。
- 通过BeanUtils创建对象实例
- 通过Constructor类的newInstance方法创建对象实例
2.4.2.4 CGLIB
若存在方法注入(replace-method、lookup-method)则必须使用CGLIB。
public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {
// 创建增强子类
Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
Object instance;
// 无参实例化
if (ctor == null) {
instance = BeanUtils.instantiateClass(subclass);
}
// 有参实例化
else {
try {
// 获取有参构造函数
Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes(
// 实例化
instance = enhancedSubclassConstructor.newInstance(args);
}
catch (Exception ex) {
throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() +
}
}
// SPR-10785: set callbacks directly on the instance instead of in the
// enhanced class (via the Enhancer) in order to avoid memory leaks.
// 为了避免内存泄漏,直接在实例上设置回调,而不是在增强类中(通过Enhancer)。
Factory factory = (Factory) instance;
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}
首先创建增强子类:
/**
* Create an enhanced subclass of the bean class for the provided bean definition, using CGLIB.
* 使用 CGLIB 为提供的 bean 定义创建 bean 类的增强子类。
*/
private Class<?> createEnhancedSubclass(RootBeanDefinition beanDefinition) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(beanDefinition.getBeanClass());
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
if (this.owner instanceof ConfigurableBeanFactory) {
ClassLoader cl = ((ConfigurableBeanFactory) this.owner).getBeanClassLoader();
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(cl));
}
enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));
enhancer.setCallbackTypes(CALLBACK_TYPES);
return enhancer.createClass();
}
Spring使用了Enhancer来创建增强子类,因为是动态字节码,所以我们需要将生成的增强文件保存到磁盘。在测试方法中添加:
// 替换成自己的路径
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/Users/liyanchao/Downloads");
OK,接下来就可以看到生成的增强子类了,因为代码较多,只粘贴核心代码:
public class OriginalDog$$EnhancerBySpringCGLIB$$236d11d6 extends OriginalDog implements Factory {
public final void sayHello() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_2;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_2;
}
if (var10000 != null) {
// 拦截方法
var10000.intercept(this, CGLIB$sayHello$0$Method, CGLIB$emptyArgs, CGLIB$sayHello$0$Proxy);
} else {
super.sayHello();
}
}
}
有了增强子类后,接下来通过instance = BeanUtils.instantiateClass(subclass);
创建对象实例,注意:这里创建的实例已经不是我们原始Bean的实例了,而是增强子类的实例。
当调用增强类中的方法时,会被intercept()方法拦截:
// replace_method
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable {
ReplaceOverride ro = (ReplaceOverride) getBeanDefinition().getMethodOverrides().getOverride(method);
Assert.state(ro != null, "ReplaceOverride not found");
// TODO could cache if a singleton for minor performance optimization
// 获取方法注入类实例
MethodReplacer mr = this.owner.getBean(ro.getMethodReplacerBeanName(), MethodReplacer.class);
return mr.reimplement(obj, method, args);
}
// lookup_method
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable {
// Cast is safe, as CallbackFilter filters are used selectively.
LookupOverride lo = (LookupOverride) getBeanDefinition().getMethodOverrides().getOverride(method);
Assert.state(lo != null, "LookupOverride not found");
Object[] argsToUse = (args.length > 0 ? args : null); // if no-arg, don't insist on args at all
if (StringUtils.hasText(lo.getBeanName())) {
Object bean = (argsToUse != null ? this.owner.getBean(lo.getBeanName(), argsToUse) :
this.owner.getBean(lo.getBeanName()));
// Detect package-protected NullBean instance through equals(null) check
return (bean.equals(null) ? null : bean);
}
else {
// Find target bean matching the (potentially generic) method return type
ResolvableType genericReturnType = ResolvableType.forMethodReturnType(method);
return (argsToUse != null ? this.owner.getBeanProvider(genericReturnType).getObject(argsToUse) :
this.owner.getBeanProvider(genericReturnType).getObject());
}
}
2.4.3 初始化bean实例
前文两个小节分2.4.1、2.4.2析了创建bean的实例(控制反转),接下来分析**初始化bean实例(依赖注入)。**在doCreateBean方法中有:
// Initialize the bean instance.
// 初始化bean实例。
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
- 步骤:
- 填充 bean 属性
- 初始化给定的 bean 实例
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.
// 应用 InstantiationAwareBeanPostProcessors 处理器
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
// 获取bean的属性
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 判断注入模式
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
// ByName 或 ByType
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;
}
// 判断是否有 InstantiationAwareBeanPostProcessor 处理器
// 该类型处理器通常用于抑制特定目标 bean 的默认实例化,一般用做 Spring 框架内部使用
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.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);
}
}
- 步骤:
- 应用 InstantiationAwareBeanPostProcessors 处理器
- 解析自动装配类型,并处理by_name、by_type两种类型
- 应用 InstantiationAwareBeanPostProcessor 处理器
- 应用给定的属性值
- 简析:
- InstantiationAwareBeanPostProcessors、InstantiationAwareBeanPostProcessor这两个处理器,后续章节分析
- by_name、by_type 留到ApplicationContext容器部分分析
- 方法代码看似繁杂,这里我们只关注applyPropertyValues()方法即可
- 小节,综上所述,我们只需要分析:
- populateBean 方法的 applyPropertyValues 方法
- initializeBean 方法
2.4.3.1 填充 bean 属性
applyPropertyValues 方法极为繁杂,只抽取其核心代码分析:
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
// 省略部分代码。。。
// 解析 PropertyValue
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
// 转换 resolvedValue
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// 应用属性值
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
// 省略部分代码。。。
}
步骤:
- 解析 PropertyValue
- 转换 resolvedValue
- 应用属性值
2.4.3.1.1 解析 PropertyValue
解析 PropertyValue 的代码繁杂,这里先概览一下其支持的类型:
- RuntimeBeanReference
- RuntimeBeanNameReference
- BeanDefinitionHolder
- BeanDefinition
- DependencyDescriptor
- ManagedArray
- ManagedList
- ManagedSet
- ManagedMap
- ManagedProperties
- TypedStringValue
- NullBean
以RuntimeBeanReference为例,分析一下其解析过程:
if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference ref = (RuntimeBeanReference) value;
return resolveReference(argName, ref);
}
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
try {
Object bean;
Class<?> beanType = ref.getBeanType();
// 从父 beanFactory 中查找
if (ref.isToParent()) {
BeanFactory parent = this.beanFactory.getParentBeanFactory();
if (parent == null) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Cannot resolve reference to bean " + ref +
" in parent factory: no parent factory available");
}
if (beanType != null) {
bean = parent.getBean(beanType);
}
else {
bean = parent.getBean(String.valueOf(doEvaluate(ref.getBeanName())));
}
}
// 从当前 beanFactory 中查找
else {
String resolvedName;
if (beanType != null) {
NamedBeanHolder<?> namedBean = this.beanFactory.resolveNamedBean(beanType);
bean = namedBean.getBeanInstance();
resolvedName = namedBean.getBeanName();
}
else {
// 解析 bean 名称
resolvedName = String.valueOf(doEvaluate(ref.getBeanName()));
// 获取 bean 实例
bean = this.beanFactory.getBean(resolvedName);
}
this.beanFactory.registerDependentBean(resolvedName, this.beanName);
}
if (bean instanceof NullBean) {
bean = null;
}
return bean;
}
catch (BeansException ex) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
}
}
其它类型不一一分析。
2.4.3.1.2 转换 resolvedValue
public <T> T convertIfNecessary(@Nullable String propertyName, @Nullable Object oldValue, @Nullable Object newValue,
@Nullable Class<T> requiredType, @Nullable TypeDescriptor typeDescriptor) throws IllegalArgumentException {
// 省略部分代码。。。
if (requiredType != null) {
// Try to apply some standard type conversion rules if appropriate.
if (convertedValue != null) {
if (Object.class == requiredType) {
return (T) convertedValue;
}
else if (requiredType.isArray()) {
// Array required -> apply appropriate conversion of elements.
if (convertedValue instanceof String && Enum.class.isAssignableFrom(requiredType.getComponentType())) {
convertedValue = StringUtils.commaDelimitedListToStringArray((String) convertedValue);
}
return (T) convertToTypedArray(convertedValue, propertyName, requiredType.getComponentType());
}
else if (convertedValue instanceof Collection) {
// Convert elements to target type, if determined.
convertedValue = convertToTypedCollection(
(Collection<?>) convertedValue, propertyName, requiredType, typeDescriptor);
standardConversion = true;
}
else if (convertedValue instanceof Map) {
// Convert keys and values to respective target type, if determined.
convertedValue = convertToTypedMap(
(Map<?, ?>) convertedValue, propertyName, requiredType, typeDescriptor);
standardConversion = true;
}
if (convertedValue.getClass().isArray() && Array.getLength(convertedValue) == 1) {
convertedValue = Array.get(convertedValue, 0);
standardConversion = true;
}
if (String.class == requiredType && ClassUtils.isPrimitiveOrWrapper(convertedValue.getClass())) {
// We can stringify any primitive value...
return (T) convertedValue.toString();
}
else if (convertedValue instanceof String && !requiredType.isInstance(convertedValue)) {
if (conversionAttemptEx == null && !requiredType.isInterface() && !requiredType.isEnum()) {
try {
Constructor<T> strCtor = requiredType.getConstructor(String.class);
return BeanUtils.instantiateClass(strCtor, convertedValue);
}
catch (NoSuchMethodException ex) {
// proceed with field lookup
if (logger.isTraceEnabled()) {
logger.trace("No String constructor found on type [" + requiredType.getName() + "]", ex);
}
}
catch (Exception ex) {
if (logger.isDebugEnabled()) {
logger.debug("Construction via String failed for type [" + requiredType.getName() + "]", ex);
}
}
}
String trimmedValue = ((String) convertedValue).trim();
if (requiredType.isEnum() && trimmedValue.isEmpty()) {
// It's an empty enum identifier: reset the enum value to null.
return null;
}
convertedValue = attemptToConvertStringToEnum(requiredType, trimmedValue, convertedValue);
standardConversion = true;
}
else if (convertedValue instanceof Number && Number.class.isAssignableFrom(requiredType)) {
convertedValue = NumberUtils.convertNumberToTargetClass(
(Number) convertedValue, (Class<Number>) requiredType);
standardConversion = true;
}
}
else {
// convertedValue == null
if (requiredType == Optional.class) {
convertedValue = Optional.empty();
}
}
if (!ClassUtils.isAssignableValue(requiredType, convertedValue)) {
if (conversionAttemptEx != null) {
// Original exception from former ConversionService call above...
throw conversionAttemptEx;
}
else if (conversionService != null && typeDescriptor != null) {
// ConversionService not tried before, probably custom editor found
// but editor couldn't produce the required type...
TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(newValue);
if (conversionService.canConvert(sourceTypeDesc, typeDescriptor)) {
return (T) conversionService.convert(newValue, sourceTypeDesc, typeDescriptor);
}
}
// Definitely doesn't match: throw IllegalArgumentException/IllegalStateException
StringBuilder msg = new StringBuilder();
msg.append("Cannot convert value of type '").append(ClassUtils.getDescriptiveType(newValue));
msg.append("' to required type '").append(ClassUtils.getQualifiedName(requiredType)).append('\'');
if (propertyName != null) {
msg.append(" for property '").append(propertyName).append('\'');
}
if (editor != null) {
msg.append(": PropertyEditor [").append(editor.getClass().getName()).append(
"] returned inappropriate value of type '").append(
ClassUtils.getDescriptiveType(convertedValue)).append('\'');
throw new IllegalArgumentException(msg.toString());
}
else {
msg.append(": no matching editors or conversion strategy found");
throw new IllegalStateException(msg.toString());
}
}
}
// 省略部分代码。。。
return (T) convertedValue;
}
2.4.3.1.3 应用属性值
// AbstractPropertyAccessor.java
public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid) throws BeansException {
// 省略部分代码。。。
try {
for (PropertyValue pv : propertyValues) {
try {
setPropertyValue(pv);
}
// 省略部分代码。。。
}
调用过程的代码不一一粘贴,最终会调用到 BeanWrapperImpl.java 的 setValue 方法:
public void setValue(@Nullable Object value) throws Exception {
// 获取 writeMethod,即 set 方法
Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
this.pd.getWriteMethod());
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(writeMethod);
return null;
});
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
() -> writeMethod.invoke(getWrappedInstance(), value), acc);
}
catch (PrivilegedActionException ex) {
throw ex.getException();
}
}
else {
ReflectionUtils.makeAccessible(writeMethod);
// 调用 JDK Method 类的 invoke 方法,设置属性值
writeMethod.invoke(getWrappedInstance(), value);
}
}
2.4.3.2 初始化 bean 实例
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 调用BeanNameAware、BeanClassLoaderAware、BeanFactoryAware接口
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 调用 postProcessBeforeInitialization 方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 调用 初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 调用 postProcessAfterInitialization 方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
initializeBean 主要涉及到与 bean 生命周期相关的接口,比较简单,不一一叙述。