Spring容器的启动流程源码解析
Spring容器启动的入口AnnotationConfigApplicationContext
本篇文章目的是对Spring的启动流程进行源码解析,不对细节做过多的分析,一些细节信息等以后的文章进行分析。这篇文章主要是让大家对Spring的启动流程有大致的了解。
本文我们以注解配置为例进行讲解,其中基于xml配置的入口是ClassPathXmlApplicationContext。
下面是AnnotationConfigApplicationContext的启动示例
public class MyApplicationContext {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
MyController bean = context.getBean(MyController.class);
}
}
@ComponentScan("com.my")
@Configuration
public class MyConfig {
}
这里MyConfig类上有@Configuration注解,说明是一个配置类,相当于xml配置的一个配置文件。然后通过@ComponentScan扫描了com.my这个包。这样我们就能把com.my包下的bean注册到bean容器了,启动完成。
前提知识了解
BeanDefinition
BeanDefinition这个就是我们所说的bean。
BeanDefinition其实就是spring对bean的一些信息的封装,它包含了bean的一些基本信息,比如是否是抽象的,是否是单例,是否是懒加载的等信息。
spring会先把bean解析为BeanDefinition,然后再创建bean的。
BeanDefinition存放在DefaultListableBeanFactory的beanDefinitionMap属性中
下面截取了BeanDefinition的部分代码。
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
String getParentName();
void setBeanClassName(String var1);
String getBeanClassName();
void setScope(String var1);
String getScope();
void setLazyInit(boolean var1);
boolean isLazyInit();
void setDependsOn(String... var1);
String[] getDependsOn();
void setAutowireCandidate(boolean var1);
boolean isAutowireCandidate();
void setPrimary(boolean var1);
boolean isPrimary();
boolean isSingleton();
boolean isPrototype();
boolean isAbstract();
}
FactoryBean
FactoryBean是Spring提供的一个可以额外创建一个对象的接口。
Spring在创建完成实现了FactoryBean接口的bean后,会调用FactoryBean接口的getObject()方法,并把该方法的返回值放到对应的缓存中(这里放入的缓存跟普通bean创建完成后放入的缓存不是同一个)。
1:那么如何获取getObject()方法返回的对象呢?
只需getBean(beanName)就能获取到
2:那么如果获取bean自身对象呢?
只需在beanName前加上&就行,getBean(&beanName)
总结:
对于没有实现FactoryBean接口的bean,getBean(beanName)方法返回的是bean自身,而对于实现了FactoryBean接口的bean返回的是getObject()方法的返回值。要想获取自身对象,则需要在beanName前加上&,比如:getBean(&beanName)
public interface FactoryBean<T> {
String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
//spring会把该方法的返回值注入到bean容器中
@Nullable
T getObject() throws Exception;
//要注入bean的类型
@Nullable
Class<?> getObjectType();
//要注入bean是否是单例
default boolean isSingleton() {
return true;
}
}
BeanPostProcessor和InstantiationAwareBeanPostProcessor接口
这两个接口是影响bean的生命周期的两个很重要的接口,不同于上面的FactoryBean接口,这两个接口可以影响多个bean的生命周期,而FactoryBean只影响当前bean的生命周期。
具体关于这两个接口的详细介绍可以看看我之前的文章:Spring Aop原理解析
AnnotationConfigApplicationContext的构造方法
我们跟进这个构造方法
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//调用空参构造方法
this();
//把MyConfig这个配置类注册到bean容器中
this.register(annotatedClasses);
//刷新容器(关键部分,是把bean解析为BeanDefinition和创建bean及aop的方法)
this.refresh();
}
首先调用了空参构造this()方法
public AnnotationConfigApplicationContext() {
//向bean容器中注册几个内置的类
this.reader = new AnnotatedBeanDefinitionReader(this);
//这个不知道有什么作用,跳过
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
这里分别创建了AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner两个类,我们来看AnnotatedBeanDefinitionReader
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
this.beanNameGenerator = new AnnotationBeanNameGenerator();
this.scopeMetadataResolver = new AnnotationScopeMetadataResolver();
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, (ResourceLoader)null);
//向bean容器中注册几个内置的类,其中ConfigurationClassPostProcessor这个类最为关键,它是解析@Configuration和@ComponentScan的关键
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, (Object)null);
}
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet(4);
RootBeanDefinition def;
//用于解析被@Configuration和@ComponentScan注解的类,扫描指定的包,把bean解析为BeanDefinition,并放到bean容器中。
if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalConfigurationAnnotationProcessor")) {
def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"));
}
if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalAutowiredAnnotationProcessor")) {
def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"));
}
if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalRequiredAnnotationProcessor")) {
def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalRequiredAnnotationProcessor"));
}
if (jsr250Present && !registry.containsBeanDefinition("org.springframework.context.annotation.internalCommonAnnotationProcessor")) {
def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalCommonAnnotationProcessor"));
}
if (jpaPresent && !registry.containsBeanDefinition("org.springframework.context.annotation.internalPersistenceAnnotationProcessor")) {
def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName("org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor", AnnotationConfigUtils.class.getClassLoader()));
} catch (ClassNotFoundException var6) {
throw new IllegalStateException("Cannot load optional framework class: org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor", var6);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalPersistenceAnnotationProcessor"));
}
if (!registry.containsBeanDefinition("org.springframework.context.event.internalEventListenerProcessor")) {
def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.event.internalEventListenerProcessor"));
}
if (!registry.containsBeanDefinition("org.springframework.context.event.internalEventListenerFactory")) {
def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.event.internalEventListenerFactory"));
}
return beanDefs;
}
Spring容器的刷新refresh(关键)
下面到了本文最重要的部分了,refresh()方法
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
//刷新容器的准备工作,记录启动时间,把容器设置为活跃状态
this.prepareRefresh();
//获取BeanFactory,对于xml配置的方式,这一步就会把bean解析为BeanDefinition
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//向bean容器添加几个内置的bean
this.prepareBeanFactory(beanFactory);
try {
//BeanFactory的后置处理方法,这里是空方法,留给子类自己实现
this.postProcessBeanFactory(beanFactory);
//(关键)执行BeanFactoryPostProcessor接口的postProcessBeanFactory方法和BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法(BeanDefinitionRegistryPostProcessor接口实现了BeanFactoryPostProcessor接口)。
//上面我们讲到的ConfigurationClassPostProcessor这个关键的类,就是实现了BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口,所以在这一步会被调用。
//ConfigurationClassPostProcessor会扫描@ComponentScan注解指定的包,并把包下的bean解析为BeanDefinition,用于后面创建这些bean。
//所以对于注解配置的方式,在这一步才会把bean解析为BeanDefinition
this.invokeBeanFactoryPostProcessors(beanFactory);
//这里获取实现BeanPostProcessors接口的bean,并提前创建这些bean,用于生成aop代理类,BeanPostProcessors是实现aop的重要接口。
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
//创建spring的事件广播类,用于广播事件
this.initApplicationEventMulticaster();
//空方法,交由子类实现
this.onRefresh();
//将事件监听器添加到广播类中
this.registerListeners();
//(关键)创建所有非抽象,单例,非懒加载的bean
this.finishBeanFactoryInitialization(beanFactory);
//完成容器刷新,发布容器刷新完成事件ContextRefreshedEvent
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
创建bean的方法finishBeanFactoryInitialization(关键)
这里直接跳到preInstantiateSingletons方法
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Pre-instantiating singletons in " + this);
}
//获取beanName集合,用于遍历创建bean
List<String> beanNames = new ArrayList(this.beanDefinitionNames);
Iterator var2 = beanNames.iterator();
while(true) {
String beanName;
Object bean;
do {
while(true) {
RootBeanDefinition bd;
do {
do {
do {
if (!var2.hasNext()) {
var2 = beanNames.iterator();
while(var2.hasNext()) {
beanName = (String)var2.next();
Object singletonInstance = this.getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, this.getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
return;
}
beanName = (String)var2.next();
bd = this.getMergedLocalBeanDefinition(beanName);
} while(bd.isAbstract());
} while(!bd.isSingleton());
} while(bd.isLazyInit());
//非懒加载,是单例,非抽象的bean会走这一步,创建bean
//判断该bean是否实现FactoryBean接口,如果实现了,那么会调用FactoryBean的getObject方法,并把该方法的返回值放到缓存中
if (this.isFactoryBean(beanName)) {
bean = this.getBean("&" + beanName);
break;
}
//创建bean
this.getBean(beanName);
}
} while(!(bean instanceof FactoryBean));
FactoryBean<?> factory = (FactoryBean)bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
SmartFactoryBean var10000 = (SmartFactoryBean)factory;
((SmartFactoryBean)factory).getClass();
isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
} else {
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
}
if (isEagerInit) {
this.getBean(beanName);
}
}
}
getBean方法
public Object getBean(String name) throws BeansException {
return this.doGetBean(name, (Class)null, (Object[])null, false);
}
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
//去除&符号,获取真正的beanName。
//对于实现了FactoryBean接口的bean,可以通过getBean(&beanName)获取自身对象,getBean(beanName)获取getObject()方法返回的对象
String beanName = this.transformedBeanName(name);
//(关键)先从一级缓存中获取实例对象,获取不到再从二级缓存中获取,再获取不到就从三级缓存中获取,如果获取到对象,就把获取的对象放到二级缓存中,最后把三级缓存中对应的对象移除。
//这一步是解决循环依赖的关键,如果二级缓存中有对象,那么就说明该对象发生了循环依赖。
//注意:如果该bean符合aop的要求的话,那么这里会提前生成aop代理对象的。
Object sharedInstance = this.getSingleton(beanName);
Object bean;
//sharedInstance不等于null,那么就说明该bean已经创建完成,并走完了生命周期了,是个完整的bean了。
if (sharedInstance != null && args == null) {
if (this.logger.isTraceEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//这里是决定返回自身对象还是实现FactoryBean接口的getObject()方法的返回值的关键
//具体的逻辑是:1:判断name是否是&开头的字符串,如果是并且该bean实现了FactoryBean接口,则返回自身对象;2:如果bean没有实现FactoryBean接口,那么就返回自身对象;3:调用FactoryBean接口的getObject()方法,返回该方法的返回值,并把返回值缓存起来。
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
//该bean还没有实例化,那么就创建该对象
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = this.getParentBeanFactory();
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
String nameToLookup = this.originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
if (args != null) {
return parentBeanFactory.getBean(nameToLookup, args);
}
if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
return parentBeanFactory.getBean(nameToLookup);
}
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
try {
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn();
String[] var11;
if (dependsOn != null) {
var11 = dependsOn;
int var12 = dependsOn.length;
for(int var13 = 0; var13 < var12; ++var13) {
String dep = var11[var13];
if (this.isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
this.registerDependentBean(dep, beanName);
try {
this.getBean(dep);
} catch (NoSuchBeanDefinitionException var24) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
}
}
}
if (mbd.isSingleton()) {
//把创建好的bean,放到一级缓存中(表示该bean是个完整的bean了),并把该bean从二级和三级缓存中移除
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
var11 = null;
Object prototypeInstance;
try {
this.beforePrototypeCreation(beanName);
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
String scopeName = mbd.getScope();
Scope scope = (Scope)this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
this.beforePrototypeCreation(beanName);
Object var4;
try {
var4 = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
return var4;
});
bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException var23) {
throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var23);
}
}
} catch (BeansException var26) {
this.cleanupAfterBeanCreationFailure(beanName);
throw var26;
}
}
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
} else {
return convertedBean;
}
} catch (TypeMismatchException var25) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var25);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
} else {
return bean;
}
}
createBean方法
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException var9) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9);
}
Object beanInstance;
try {
//获取bean容器中所有实现InstantiationAwareBeanPostProcessor接口的bean,并遍历调用postProcessBeforeInstantiation方法,这个方法是进行aop之前的准备工作。具体可以看看我之前关于aop的文章
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if (beanInstance != null) {
return beanInstance;
}
} catch (Throwable var10) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
}
try {
//到了真正创建bean的方法了
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
} catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
throw var7;
} catch (Throwable var8) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
}
}
doCreateBean方法
真正创建bean的doCreateBean方法
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//实例化bean,此时仅仅是创建了bean,bean的属性并没有被填充
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable var17) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
}
mbd.postProcessed = true;
}
}
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
//把刚实例化的bean放到三级缓存中
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
Object exposedObject = bean;
try {
//填充bean的属性
this.populateBean(beanName, mbd, instanceWrapper);
//初始化bean
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable var18) {
if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
throw (BeanCreationException)var18;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
}
if (earlySingletonExposure) {
//去一级缓存和二级缓存中去取bean
Object earlySingletonReference = this.getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
//取到了bean,说明该bean有循环依赖,由于aop的存在,导致在循环依赖时,会提前创建aop的代理类,并且代理类只创建一次。
//为了保证依赖该bean的其它bean,获取的bean和该bean一样,就把该bean替换为循环依赖时生成的bean。
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
String[] dependentBeans = this.getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
String[] var12 = dependentBeans;
int var13 = dependentBeans.length;
for(int var14 = 0; var14 < var13; ++var14) {
String dependentBean = var12[var14];
if (!this.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.");
}
}
}
}
try {
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
} catch (BeanDefinitionValidationException var16) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
}
}