在前面的兩篇博文《一次性講清楚spring中bean的生命週期之一:getSingleton方法》和《一次性講清楚spring中bean的生命週期之二:FactoryBean的前世今生》中分析了spring中bean生命週期的過程中的getSingleton方法和getObjectForBeanInstance方法,今天來分析另外一個重要的方法createBean方法。分析的入口是AbstractBeanFacotry.doGetBean方法,如下圖,

這就是本次分析的入口。下面看該方法的詳細定義,AbstractAutowireCapableBeanFactory.createBean

@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);
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.
//給beanPostProcessor一個返回目標類代理類的機會
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 {
//執行doCreatBean方法
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);
}
}

重點部分已用紅色標出,下面具體來分析

bean生命週期前

在上面的方法定義中有這樣一段程式碼,

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

就是說在進入bean的建立之前,開發者可以自己返回一個目標類的代理類,如果返回了那麼便直接返回,不會繼續向下執行。看該方法怎麼實現的,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) {
//應用BeanPostProcessor例項化前
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//應用BeanpPostProcessor初始化後
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}

該方法重要的就是applyBeanPostProcessorsBeforeInstantiation和applyBeanPostProcessorsAfterInitalization方法。

applyBeanPostProcessorsBeforeInstantiation

@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//在spring中有InstantiationAwareBeanPostProcessor的例項,則執行其postProcessBeforeInstantiation方法
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}

該方法的主要作用是如果在spring中有InstantiationAwareBeanPostProcessor型別的beanPostProcessor的化,會執行其postProcessBeforeInstantiation方法,也就是我們可以實現InstantiationAwareBeanPostProcessor介面,並實現其postProcessBeforeInstantiation方法。預設情況下該介面的方法返回null,

@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}

applyBeanPostProcessorsAfterInitalization

回過頭來看另外一個方法,

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException { Object result = existingBean;
//遍歷spring容器中所有的beanPostProcessor,執行其postProcessAfterInitialization方法
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}

BeanPostProcessor介面中該方法預設返回如下

@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}

在spring容器中會有多少BeanPostProcessor這個後面會分析。

分析完了進入bean生命週期前的方法,也就是留個開發者一個後門,通過實現InstantiationAwareBeanPostProcessor介面中的postProcessBeforeInstantiation方法可以自定義返回一個目標型別的代理物件。現在回到createBean方法中,真正進入bean的生命週期,看doCreateBean方法,

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) {
//例項化bean
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
} .... // 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");
}
//放到singletonFactory中解決迴圈依賴的問題
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
} // Initialize the bean instance.
Object exposedObject = bean;
try {
//屬性注入
populateBean(beanName, mbd, instanceWrapper);
//初始化bean
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);
}
} .... return exposedObject;
}

看createBeanInstance方法

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); 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<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
//使用例項工廠或靜態工廠的方式生成bean例項
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
} // Shortcut when re-creating the same 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,其實就是使用類的構造方法來進行例項化,這裡看下instantiateBean方法的過程,

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 {
//生成bean的例項
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
//構造一個beanWrapper物件
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}

從上面的程式碼可以看到該方法中重要的就是下面這句

beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);

看下getInstantiationStrategy()方法返回什麼,

/**
* Return the instantiation strategy to use for creating bean instances.
*/
protected InstantiationStrategy getInstantiationStrategy() {
return this.instantiationStrategy;
}

返回的是一個屬性,

/** Strategy for creating bean instances. */
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();

是一個CglibSubclassingInstantiationStragegy物件,看其instantiate方法,由於CglibSubclassingInstantiationStrategy繼承了SimpleInstantiationStrategy類,該方法在父類SimpleInstantiationStrategy中

@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
//如果沒有使用lookup或replaced,不使用CGLIB重寫該類
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);
}
}

從上面可以看出有兩種方式生成例項,使用反射的機制

return BeanUtils.instantiateClass(constructorToUse);

如果有lookup或replaced,使用cglib方式

return instantiateWithMethodInjection(bd, beanName, owner);

BeanUtils.instantiateClass(反射)

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}

標紅的程式碼就是生成的邏輯,可以看到是利用的java的反射機制,也就是使用Constructor類的newInstance方法。

instantiateWithMethodInjection(cglib)

該方法在CglibSubclassingInstantiationStrategy中

@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
return instantiateWithMethodInjection(bd, beanName, owner, null);
}
@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Constructor<?> ctor, Object... args) { // Must generate CGLIB subclass...
return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
}

使用的是CglibSubclassCreator生成的例項,具體方式就是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() + "]", ex);
}
}
// SPR-10785: set callbacks directly on the instance instead of in the
// enhanced class (via the Enhancer) in order to avoid memory leaks.
Factory factory = (Factory) instance;
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}

分析完畢spring中單例bean的例項化過程。

總結

至此分析完了spring中單例bean的例項化過程,主要有兩點,

1、類中有lookup或replaced方式,使用cglib的方式生成bean的例項;

2、類中無lookup或replaced方式,使用java反射機制Constructor生成例項;

推薦閱讀

一次性講清楚spring中bean的生命週期之二:FactoryBean的前世今生 》

一次性講清楚spring中bean的生命週期之一:getSingleton方法