千家信息网

Spring的单例Bean初始化过程是什么

发表于:2024-10-14 作者:千家信息网编辑
千家信息网最后更新 2024年10月14日,本篇内容介绍了"Spring的单例Bean初始化过程是什么"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所
千家信息网最后更新 2024年10月14日Spring的单例Bean初始化过程是什么

本篇内容介绍了"Spring的单例Bean初始化过程是什么"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

createBean方法是AbstractBeanFactory的子类AbstractAutowireCapableBeanFactory的一个方法,看一下它的方法实现:

protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)

throws BeanCreationException {

if (logger.isDebugEnabled()) {

logger.debug("Creating instance of bean '" + beanName + "'");

}

// Make sure bean class is actually resolved at this point.

resolveBeanClass(mbd, beanName);

// Prepare method overrides.

try {

mbd.prepareMethodOverrides();

}

catch (BeanDefinitionValidationException ex) {

throw new BeanDefinitionStoreException(mbd.getResourceDescription(),

beanName, "Validation of method overrides failed", ex);

}

try {

// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.

Object bean = resolveBeforeInstantiation(beanName, mbd);

if (bean != null) {

return bean;

}

}

catch (Throwable ex) {

throw new BeanCreationException(mbd.getResourceDescription(), beanName,

"BeanPostProcessor before instantiation of bean failed", ex);

}

Object beanInstance = doCreateBean(beanName, mbd, args);

if (logger.isDebugEnabled()) {

logger.debug("Finished creating instance of bean '" + beanName + "'");

}

return beanInstance;

}

前面的代码都没什么意义,代码执行到第31行:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {

// Instantiate the bean.

BeanWrapper instanceWrapper = null;

if (mbd.isSingleton()) {

instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);

}

if (instanceWrapper == null) {

instanceWrapper = createBeanInstance(beanName, mbd, args);

}

final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);

Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

// Allow post-processors to modify the merged bean definition.

synchronized (mbd.postProcessingLock) {

if (!mbd.postProcessed) {

applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

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.isDebugEnabled()) {

logger.debug("Eagerly caching bean '" + beanName +

"' to allow for resolving potential circular references");

}

addSingletonFactory(beanName, new ObjectFactory() {

public Object getObject() throws BeansException {

return getEarlyBeanReference(beanName, mbd, bean);

}

});

}

// Initialize the bean instance.

Object exposedObject = bean;

try {

populateBean(beanName, mbd, instanceWrapper);

if (exposedObject != null) {

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 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 " +

"'getBeanNamesOfType' 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;

}

代码跟踪到这里,已经到了主流程,接下来分段分析doCreateBean方法的代码。

创建Bean实例

第8行的createBeanInstance方法,会创建出Bean的实例,并包装为BeanWrapper,看一下createBeanInstance方法,只贴最后一段比较关键的:

// Need to determine the constructor...

Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);

if (ctors != null ||

mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||

mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {

return autowireConstructor(beanName, mbd, ctors, args);

}

// No special handling: simply use no-arg constructor.

return instantiateBean(beanName, mbd);

意思是bean标签使用构造函数注入属性的话,执行第6行,否则执行第10行。MultiFunctionBean使用默认构造函数,使用setter注入属性,因此执行第10行代码:

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {

try {

Object beanInstance;

final BeanFactory parent = this;

if (System.getSecurityManager() != null) {

beanInstance = AccessController.doPrivileged(new PrivilegedAction() {

public Object run() {

return getInstantiationStrategy().instantiate(mbd, beanName, parent);

}

}, getAccessControlContext());

}

else {

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

}

BeanWrapper bw = new BeanWrapperImpl(beanInstance);

initBeanWrapper(bw);

return bw;

}

catch (Throwable ex) {

throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);

}

}

代码执行到13行:

public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {

// Don't override the class with CGLIB if no overrides.

if (beanDefinition.getMethodOverrides().isEmpty()) {

Constructor constructorToUse;

synchronized (beanDefinition.constructorArgumentLock) {

constructorToUse = (Constructor) beanDefinition.resolvedConstructorOrFactoryMethod;

if (constructorToUse == null) {

final Class clazz = beanDefinition.getBeanClass();

if (clazz.isInterface()) {

throw new BeanInstantiationException(clazz, "Specified class is an interface");

}

try {

if (System.getSecurityManager() != null) {

constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction() {

public Constructor run() throws Exception {

return clazz.getDeclaredConstructor((Class[]) null);

}

});

}

else {

constructorToUse = clazz.getDeclaredConstructor((Class[]) null);

}

beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;

}

catch (Exception ex) {

throw new BeanInstantiationException(clazz, "No default constructor found", ex);

}

}

}

return BeanUtils.instantiateClass(constructorToUse);

}

else {

// Must generate CGLIB subclass.

return instantiateWithMethodInjection(beanDefinition, beanName, owner);

}

}

整段代码都在做一件事情,就是选择一个使用的构造函数。当然第9行顺带做了一个判断:实例化一个接口将报错。

最后调用到30行,看一下代码:

public static T instantiateClass(Constructor ctor, Object... args) throws BeanInstantiationException {

Assert.notNull(ctor, "Constructor must not be null");

try {

ReflectionUtils.makeAccessible(ctor);

return ctor.newInstance(args);

}

catch (InstantiationException ex) {

throw new BeanInstantiationException(ctor.getDeclaringClass(),

"Is it an abstract class?", ex);

}

catch (IllegalAccessException ex) {

throw new BeanInstantiationException(ctor.getDeclaringClass(),

"Is the constructor accessible?", ex);

}

catch (IllegalArgumentException ex) {

throw new BeanInstantiationException(ctor.getDeclaringClass(),

"Illegal arguments for constructor", ex);

}

catch (InvocationTargetException ex) {

throw new BeanInstantiationException(ctor.getDeclaringClass(),

"Constructor threw exception", ex.getTargetException());

}

}

通过反射生成Bean的实例。看到前面有一步makeAccessible,这意味着即使Bean的构造函数是private、protected的,依然不影响Bean的构造。

最后注意一下,这里被实例化出来的Bean并不会直接返回,而是会被包装为BeanWrapper继续在后面使用。

"Spring的单例Bean初始化过程是什么"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

0