细谈Bean的实例化过程
文章目录
我们都知道,在执行以下的一行代码后,我们就可以调用在knight.xml文件中配置的bean了。
那么context的内部究竟长什么样?它又是在哪里,以何种方式实现了依赖注入?
ApplicationContext context = new ClassPathXmlApplicationContext("knight.xml");
以ClassPathXmlApplicationContext为例追溯Bean的实例化过程
声明:源代码为Spring 5.0版本
ClassPathXmlApplicationContext的继承与实现关系
DefaultListableBeanFactory的继承与实现关系
ClassPathXmlApplicationContext的构造函数
首先查看ClassPathXmlApplicationContext的构造函数:
// org.springframework.context.support.ClassPathXmlApplicationContxt
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
可以看到,在其构造函数中,调用了refresh()方法。该方法定义在ClassPathXmlApplicationContext的父父…父接口AbstractApplicationContext中:
// org.springframework.context.support.AbstractApplicationContext
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory. (1)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons. (2)
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
contextRefresh.end();
}
}
}
我们知道,对Bean的实例化操作是由BeanFactory实现的,ApplicationContext在此之外扩展了一些功能。在refresh()方法中和bean实例化相关的代码主要为(1),(2)两行。
我们还知道,BeanFactory初始化Bean分为两步
第一步是容器的启动阶段:容器加载Configuration MetaData,使用工具类(BeanDefinitionReader)解析元数据,注册BeanDefinition到相应的BeanDefinitionRegistry。
第二步是Bean的实例化阶段:当某个请求调用getBean()方法时,根据BeanDefinition实例化这个Bean。
AbstractContext的refresh方法中这两行代码正好对应了这两个操作:
第一行代码初始化一个BeanFactory,用它来注册所有的BeanDefinition
第二行代码集中调动getBean方法,实例化所有Bean
(这也是为什么BeanFactory延迟初始化,而ApplicationContext在一开始就初始化)
注册BeanDefinition的逻辑所在
我们先看ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
这行:
// org.springframework.context.support.AbstractApplicationContext
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
getBeanFactory()就是返回类中定义的BeanFactory属性,我们主要关注refreshBeanFactory()方法
该方法的实现写在AbstractRefreshableApplicationContext类里:
(搞不清这几个类之间关系的可以拉到前面再看一遍类图)
// org.springframework.context.support.AbstractRefreshableApplicationContext
/**
* This implementation performs an actual refresh of this context's underlying
* bean factory, shutting down the previous bean factory (if any) and
* initializing a fresh bean factory for the next phase of the context's lifecycle.
*/
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
在refreshBeanFactory()方法中,首先判断是否已经初始化了一个BeanFactory,若有,就destroy掉。
先创建了一个DefaultListableBeanFactory对象,然后调用loadBeanDefinitions()方法
我们先看loadBeanDefinitions()方法,该方法的实现和你使用哪种Configuration MetaData有关,我们使用Xml文件加载配置,方法的实现写在AbstractXmlApplicationContext类中:
// org.springframework.context.support.AbstractXmlApplicationContext
/**
* Loads the bean definitions via an XmlBeanDefinitionReader.
*@seeorg.springframework.beans.factory.xml.XmlBeanDefinitionReader
*@see#initBeanDefinitionReader
*@see#loadBeanDefinitions
*/
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
/**
* Initialize the bean definition reader used for loading the bean
* definitions of this context. Default implementation is empty.
*<p>Can be overridden in subclasses, e.g. for turning off XML validation
* or using a different XmlBeanDefinitionParser implementation.
*@paramreaderthe bean definition reader used by this context
*@seeorg.springframework.beans.factory.xml.XmlBeanDefinitionReader#setDocumentReaderClass
*/
protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
reader.setValidating(this.validating);
}
/**
* Load the bean definitions with the given XmlBeanDefinitionReader.
*<p>The lifecycle of the bean factory is handled by the {@link#refreshBeanFactory}
* method; hence this method is just supposed to load and/or register bean definitions.
*@paramreaderthe XmlBeanDefinitionReader to use
*@throwsBeansException in case of bean registration errors
*@throwsIOException if the required XML document isn't found
*@see#refreshBeanFactory
*@see#getConfigLocations
*@see#getResources
*@see#getResourcePatternResolver
*/
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
该方法的逻辑大概如下:
创建一个BeanDefinitionReader实例对象⇒配置并初始化该reader对象⇒使用reader对象根据Resources加载BeanDefinition
BeanDefinitionReader是如何解析xml文件的就不去探讨了,接下来我们研究一下DefaultListableBeanFactory类
实例化Bean的逻辑——getBean方法是怎么调用到的
我们回到AbstractApplicationContext类的refresh()方法,该方法的(2)代码如下所示:
finishBeanFactoryInitialization(beanFactory);
根据官方注释,这行代码实例化所有的非延迟加载的单例对象
// org.springframework.context.support.AbstractApplicationContext
/**
* Finish the initialization of this context's bean factory,
* initializing all remaining singleton beans.
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beaFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// (3)
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// (4)
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
(3)处的代码,获取所有在类加载时织入的bean的名称,然后调用它们的getBean方法。
当然我们的重点不在这,而是在(4)处的代码:beanFactory.preInstantiateSingletons();
在这一步,我们所定义的所有非懒加载的单例对象,都将被实例化。
该方法的方法体写在DefaultListableBeanFactory类里
// org.springframework.beans.factory.support.DefaultListableBeanFactory
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 不是抽象 & 是单例 & 不是懒加载
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 如果该bean是一个factorybean对象,那么在beanName前加一个前缀'&'再实例化
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX+ beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
// 不是factorybean,即一般对象,调用getbean方法实例化
else {
getBean(beanName);
}
}
}
...
}
看中间有中文注释的那部分,首先筛查出需要预实例化的bean:
- 不是抽象的
- scope是singleton
- 不是声明为延迟初始化的
如果该bean是factoryBean类型,那么在beanName上加上一个&前缀再实例化;如果非factorybean,那么直接调用getBean()方法
getBean()
getBean()方法实现在AbstractBeanFactory里:
// org.springframework.beans.factory.support.AbstractBeanFactory
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
doGetBean()的实现也在AbstractBeanFactory类里,它的源码太长了,我就不贴了。
大致逻辑是:
调用getSingleton(beanName)方法获取该bean的单例对象,如果不是null,那么会返回该对象;如果该对象为空,那么:
- 通过beanName获取BeanDefinition,并调用getBean获取该Bean所依赖的其他bean。
- 注册所依赖的bean
- 如果beanDefinition是singleton类型,那么调用createbean()方法创建一个bean对象,并将单例对象引用指向这个对象。
- 如果beanDefinition是prototype类型,那么创建新对象并返回。
还是贴个代码框架吧,删掉了和主要逻辑无关的代码:
// org.springframework.beans.factory.support.AbstractBeanFactory
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
String beanName = transformedBeanName(name);
Object beanInstance;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
...
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
...
try {
...
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
...
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
...
}
}
}
// Create bean instance.
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);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
...
}
return adaptBeanInstance(name, beanInstance, requiredType);
}
真正的Bean实例化逻辑——createBean()
createBean()的实现写在AbstractAutowireCapableBeanFactory(DefaultListableBeanFactory的父类),该方法调用了doCreateBean方法来实例化单例对象
doCreateBean()代码如下所示:
/**
* Actually create the specified bean. Pre-creation processing has already happened
* at this point, e.g. checking {@codepostProcessBeforeInstantiation} callbacks.
*<p>Differentiates between default bean instantiation, use of a
* factory method, and autowiring a constructor.
*@parambeanNamethe name of the bean
*@parammbdthe merged bean definition for the bean
*@paramargsexplicit arguments to use for constructor or factory method invocation
*@returna new instance of the bean
*@throwsBeanCreationException if the bean could not be created
*@see#instantiateBean
*@see#instantiateUsingFactoryMethod
*@see#autowireConstructor
*/
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the 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.
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.
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.
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.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
我们可以搭配一张图来理解Bean的实例化过程:
(图源《Spring揭秘》)
1. 实例化bean对象
这一部分的代码就写在doCreateBean方法内
容器调用了createBeanInstance()方法,createBeanInstance()方法又调用了instantiateBean方法,instantiateBean()代码如下所示:
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 {
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);
}
}
可以看到在该方法中,调用了getInstantiationStrategy().instantiate(…)方法,由方法名可以看出,容器使用了策略模式。默认情况下,容器内部采用CglibSubclassingInstantiationStrategy。该策略类使用反射方式生成类,并借助Cglib的动态字节码生成功能,可以动态生成某个类的子类。
该方法返回一个BeanWrapper对象,BeanWrapper是对Bean的一个包装,可以设置或获取bean的相应属性值。
2. 设置对象属性
instantiateBean()创建完BeanWrapper后不是立即返回,而是调用initBeanWraper()方法
initBeanWrapper方法实现于AbstractBeanFactory类中,因为BeanWrapper也实现自PropertyEditorRegistry接口,所以可以复制一份PropertyEditor,用于转换类型、设置对象属性。
/**
* Initialize the given BeanWrapper with the custom editors registered
* with this factory. To be called for BeanWrappers that will create
* and populate bean instances.
*<p>The default implementation delegates to {@link#registerCustomEditors}.
* Can be overridden in subclasses.
*@parambwthe BeanWrapper to initialize
*/
protected void initBeanWrapper(BeanWrapper bw) {
bw.setConversionService(getConversionService());
registerCustomEditors(bw);
}
3. BeanPostProcessor前置处理和检查Aware接口并设置相关依赖
这两步放在一块讲,因为在代码中的执行顺序与流程图的顺序相反。
先执行BeanPostProcessor前置处理:
// Allow post-processors to modify the merged bean definition.
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.
// 是单例 & 允许循环引用 & 正在创建该单例
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));
}
然后执行initialBean()方法
initalBean()方法中共调用了三个其他方法:
- invokeAwareMethods(beanName, bean)
- invokeInitMethods(beanName, wrappedBean, mbd)
- applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)
invokeAwareMethods方法即检查Aware相关接口并设置依赖:
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
4. 检测是否是InitializingBean以决定是否调用afterPropertiesSet()
initalBean()所调用的第二个方法invokeInitMethods代码如下所示:
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
InitializingBean是容器内部广泛使用的一个对象声明周期接口,如果检测到当前对象实现了这个接口,会调用afterPropertiesSet()方法进一步调整对象实例的状态。比如,在有些情况下,某个对象实例化完成后,还不能处于可以使用的状态,这时就应该让该对象实现这个接口,并在afterPropertiesSet方法中定义后续处理。
5. init-method
invokeInitMethod方法中调用了invokeCustomInitMethod方法执行用户定义的初始化操作
在xml中,我们通过标签定义需要在初始化后、使用之前调用的方法
6. BeanPostProcessor后续处理
initalBean()调用的第三个方法——applyBeanPostProcessorsAfterInitialization完成了后续处理
7. 可以使用了!
initalBean()执行完成后,会返回一个Object对象,如果不是循环依赖,此时该object已经可以使用了。
如果是循环依赖,因为之前创建的object的依赖为空,所以要更新这个对象。
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.");
}
}
}
}
8. DisposableBean与destory-method
doCreateBean的最后几行代码,如果bean实现了DisposableBean接口,或通过destory-method定义了对象销毁方法,那么会为该实例注册一个用于对象销毁的回调。在这些对象实例销毁之前,执行回调。
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}