妈妈说,文章标题取得越长,文章阅读量越高。hhhhh
在AbstractBeanFactory#doGetBean方法中会通过如下方法来创建单例Bean:
if (mbd.isSingleton()) {
// 创建单例Bean
sharedInstance = getSingleton(beanName, () -> {
try {
// 创建Bean
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);
让我们来看一下getSingleton方法:
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
//判断单例Bean是否已经存在,如果存在,则直接返回
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 + "'");
}
// 创建单例之前调用该方法,将此Bean标记为正在创建中,用来检测循环依赖
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 通过方法传入的ObjectFactory<?> singletonFactory来创建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) {
// 加入到单例池容器中
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
通过源码我们可以知道,在getSingleton方法中是通过调用传入的ObjectFactory<?> singletonFactory对象的getObject();方法来创建单例Bean的,而该方法其实是AbstractAutowireCapableBeanFactory#createBean方法。
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引用(如果需要,并将解析后的Class存储在bean定义中以备将来使用),也就是通过类加载去加载这个Class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
// 校验和准备 Bean 中的方法覆盖
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 , 给 BeanPostProcessors 一个机会直接返回代理对象来代替Bean实例
// 在Bean还没有开始实例化之前执行 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation方法,这个方法可能会直接返回Bean
// 如果这里直接返回了Bean,那么这里返回的Bean可能是被经过处理的Bean(可能是代理对象)
// 在这里需要注意Spring方法中的两个单词: Instantiation 和 Initialization , 实例化和初始化, 先实例化,然后初始化
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
// 如果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);
}
}
总的来看createBean方法,大概经历了如下几个步骤:
-
调用
resolveBeanClass(mbd, beanName);方法,为指定的bean定义解析bean类 -
调用
mbdToUse.prepareMethodOverrides();方法,校验和准备 Bean中的方法覆盖 -
调用
resolveBeforeInstantiation(beanName, mbdToUse);方法,给BeanPostProcessors一个机会直接返回代理对象来代替Bean实例 -
调用
doCreateBean(beanName, mbdToUse, args);方法,真正执行Bean的创建
resolveBeforeInstantiation
在createBean方法中最重要的方法之一就是resolveBeforeInstantiation(beanName, mbdToUse);。
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;
}
在resolveBeforeInstantiation方法内部执行了两个BeanPostProcessor的相关方法,分别是: applyBeanPostProcessorsBeforeInstantiation和applyBeanPostProcessorsAfterInitialization。
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) {
return result;
}
}
}
return null;
}
该方法在Bean实例化之前调用,给BeanPostProcessor一个机会去创建代理对象来代理Bean。
也就是说,经过调用InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation方法之后,生成的Bean可能已经不是我们的原生Bean,而是一个代理对象。
applyBeanPostProcessorsAfterInitialization
在执行InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation方法后,如果返回的Bean对象不为null,则直接执行applyBeanPostProcessorsAfterInitialization方法,执行完后Bean创建过程结束。
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
doCreateBean
在执行完resolveBeforeInstantiation方法之后,如果返回的对象还是为null,则调用doCreateBean(beanName, mbdToUse, args);方法来创建Bean。
看了这么多Spring的源码,Spring的编码风格就是这样,真正干活的方法往往都是do开头的方法,例如doXxxx方法。
关于doCreateBean方法的具体源码,我们下期在解析。现在我们在来讲一下InstantiationAwareBeanPostProcessor。
InstantiationAwareBeanPostProcessor初探
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
return null;
}
@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
InstantiationAwareBeanPostProcessor继承了BeanPostProcessor接口。
Subinterface of BeanPostProcessor that adds a before-instantiation callback, and a callback after instantiation but before explicit properties are set or autowiring occurs.
Typically used to suppress default instantiation for specific target beans, for example to create proxies with special TargetSources (pooling targets, lazily initializing targets, etc), or to implement additional injection strategies such as field injection.
NOTE: This interface is a special purpose interface, mainly for internal use within the framework. It is recommended to implement the plain BeanPostProcessor interface as far as possible, or to derive from InstantiationAwareBeanPostProcessorAdapter in order to be shielded from extensions to this interface.
BeanPostProcessor的子接口,它添加实例化之前的回调,以及在实例化之后但在设置显式属性或发生自动装配之前的回调。
通常用于抑制特定目标Bean的默认实例化,例如创建具有特殊TargetSource的代理(池目标,延迟初始化目标等),或实现其他注入策略,例如字段注入。
注意:此接口是专用接口,主要供框架内部使用。 建议尽可能实现普通的BeanPostProcessor接口,或从InstantiationAwareBeanPostProcessorAdapter派生,以免对该接口进行扩展。
postProcessBeforeInstantiation
这次我们先重点关注一下InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation方法。这个方法有什么用呢?一起来看一下doc文档的描述:
Apply this BeanPostProcessor before the target bean gets instantiated
If a non-null object is returned by this method, the bean creation process will be short-circuited. The only further processing applied is the
BeanPostProcessor.postProcessAfterInitialization(java.lang.Object, java.lang.String)callback from the configuredBeanPostProcessors.This callback will be applied to bean definitions with their bean class, as well as to factory-method definitions in which case the returned bean type will be passed in here.
Post-processors may implement the extended
SmartInstantiationAwareBeanPostProcessorinterface in order to predict the type of the bean object that they are going to return here.The default implementation returns
null.在实例化目标bean之前应用此BeanPostProcessor。 返回的bean对象可以是代替目标bean使用的代理,从而有效地抑制了目标bean的默认实例化。 如果此方法返回一个非null对象,则Bean创建过程将被短路。 唯一应用的进一步处理是来自已配置BeanPostProcessors的BeanPostProcessor.postProcessAfterInitialization(java.lang.Object,java.lang.String)回调。
此回调将应用于具有其bean类的bean定义以及工厂方法定义,在这种情况下,返回的bean类型将在此处传递。
后处理器可以实现扩展的SmartInstantiationAwareBeanPostProcessor接口,以便预测它们将在此处返回的Bean对象的类型。
默认实现返回null。
举个例子
有这样一个Bean,代码如下:
@Service
public class UserService {
public UserService() {
System.out.println("create UserService...");
}
@PostConstruct
public void init() {
System.out.println("do init...");
}
@PreDestroy
public void destroy() {
System.out.println("do destroy...");
}
}
正常情况下,该在Bean在生命周期内,应该会输出:
create UserService...
do init...
do destroy...
现在,让我们添加一个自定义的InstantiationAwareBeanPostProcessor,来干预UserService的生命周期。
@Component
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (UserService.class.equals(beanClass)) {
return new UserService();
}
return null;
}
}
MyInstantiationAwareBeanPostProcessor继承了InstantiationAwareBeanPostProcessorAdapter,同时Override了postProcessBeforeInstantiation方法。
此时,该在Bean在生命周期内输出:
create UserService...
为什么呢?不知道聪明的读者读完这篇文章能不能自己分析出原因。
未完待续......
源码注释GITHUB地址:github.com/shenjianeng…
欢迎关注公众号:
