妈妈说,文章标题取得越长,文章阅读量越高。hhhhhhtml
在AbstractBeanFactory#doGetBean
方法中会经过以下方法来建立单例Bean:java
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
方法:git
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
方法。github
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
方法,大概经历了以下几个步骤:spring
调用resolveBeanClass(mbd, beanName);
方法,为指定的bean定义解析bean类api
调用mbdToUse.prepareMethodOverrides();
方法,校验和准备 Bean中的方法覆盖app
调用resolveBeforeInstantiation(beanName, mbdToUse);
方法,给BeanPostProcessors
一个机会直接返回代理对象来代替Bean实例框架
调用doCreateBean(beanName, mbdToUse, args);
方法,真正执行Bean的建立ide
在createBean
方法中最重要的方法之一就是resolveBeforeInstantiation(beanName, mbdToUse);
。post
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
。
@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,而是一个代理对象。
在执行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;
}
复制代码
在执行完resolveBeforeInstantiation
方法以后,若是返回的对象仍是为null,则调用doCreateBean(beanName, mbdToUse, args);
方法来建立Bean。
看了这么多Spring的源码,Spring的编码风格就是这样,真正干活的方法每每都是do
开头的方法,例如doXxxx
方法。
关于doCreateBean
方法的具体源码,咱们下期在解析。如今咱们在来说一下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派生,以避免对该接口进行扩展。
此次咱们先重点关注一下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
SmartInstantiationAwareBeanPostProcessor
interface 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…
欢迎关注公众号: