Written in the book before
In the previous article, the design idea of SpringIOC container, as well as the loading process of SpringIOC was a simple introduction, and then through Spring source code to load IOC to carry out a detailed analysis.
Source code analysis
The this() constructor is called first.
Can see AnnotationConfigApplicationContext inherited GenericApplicationContext, therefore in the call this () constructor, will go to call the superclass constructor.
In the superclass constructor for ApplicationContext initial the beanFactory spring context object, through the class diagram you can see, DefaultListableBeanFactory is at the bottom of the implementation, function is the most comprehensive. A read is then created in the constructor of the subclassThe annotated Bean defines the readerIn which there is a registration of spring’s internal BeanDefinition, mainly the post-processor. It’s going to initialize another oneThe Bean defines the scannerCan be used to scan packets. Spring the default scan package is not the scanner object, but their new a ClassPathBeanDefinitionScanner, spring when performing engineering ConfigurationClassPostProcessor post processor, To scan the package will be new a ClassPathBeanDefinitionScanner, the scanner here merely for developers can be manually invoked AnnotationConfigApplicationContext scan method of objects.
And then go intoAnnotatedBeanDefinitionReaderConstructor, you can see some registered hereBuilt-in rear processor:
- CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME: Name: org. Springframework. Context. The annotation. InternalConfigurationAnnotationProcessor, Corresponding is ConfigurationClassPostProcessor class, it implements the spring BeanFactoryPostProcessor, post processor. Is mainly responsible for the resolution of Configuration class, in this class, will resolve the Configuration class with @Configuration, will also resolve @ComponentScan, @ComponentScans annotations scanned package, and resolve @import annotations.
- AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME: Name: org. Springframework. Context. The annotation. InternalAutowiredAnnotationProcessor, used to resolve the @autowired annotation.
The this() constructor is followed by register(annotatedClasses), which registers the configuration classes, and then does the main thingdoRegisterBeanMethods.
After performing a series of operations in this, such as setting the scope of the Bean to a singleton by default, etc. The last thing to do is register BeanDefinition. It will end up callingDefaultListableBeanFactoryIn theregisterBeanDefinitionMethods to register, DefaultListableBeanFactory maintains a series of information, such as beanDefinitionNames beanDefinitionMap, BeanDefinitionNames is a List that holds beanName, and beanDefinitionMap is a Map that holds beanName and beanDefinition.
If you go here you can see that in BeanDefinitionMap, you already have itBeanDefinition of its own configuration classandSome of the internal post-processors registered above.
And then you go inrefresh()This method is at the heart of Spring, where most of the process logic is handled.
So let’s look at these two methods,invokeBeanFactoryPostProcessorsBasically calling our bean factory’s post-processor:
- 1. Class is scanned here as beanDefinition;
- 2. Bean factory post-processor call;
finishBeanFactoryInitialization(beanFactory)Method to instantiate the remaining singleton beans.
Don’t go to see the first invokeBeanFactoryPostProcessors method, after will find that more than two BeanDefinition BeanDefinitionMap, These are the two classes scanned by @ComponentScan() in MainConfig.java and handled in this method.
Then see finishBeanFactoryInitialization method:
As shown in the above comment, if it is not a FactoryBean then the getBean() method is used.
Insert a little question: What are factoryBeans? What does it have to do with BeanFactory?
The answer is that it doesn’t matter, a FactoryBean is a special Bean, for example:
If the FactoryBean interface is implemented, SpringIOC calls the getObject() method, which returns an object that can be customized. An error is reported when a getBean is forcibly converted to Car. It cannot be forcibly converted because it returns a Tank object. If you must get the car, do it inAdd & to carThe symbol retrieves the original CAR object.
Ok, then proceed to the getBean() method, where the main processing logic is in the doGetBean() method:
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
/**
* 在这里 传入进来的name 可能是 别名, 也有可能是工厂bean的name,所以在这里需要转换
*/
final String beanName = transformedBeanName(name);
Object bean;
//尝试去缓存中获取对象,第一次刚进来是获取不到即为空,可以到下面的getSingleton方法查看源码内容
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
/**
* /*
* 如果 sharedInstance 是普通的单例 bean,下面的方法会直接返回。但如果
* sharedInstance 是 FactoryBean 类型的,则需调用 getObject 工厂方法获取真正的
* bean 实例。如果用户想获取 FactoryBean 本身,这里也不会做特别的处理,直接返回
* 即可。毕竟 FactoryBean 的实现类本身也是一种 bean,只不过具有一点特殊的功能而已。
*/
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
/**
* 判断是不是多例Bean,spring 只能解决单例对象的setter 注入的循环依赖,不能解决构造器注入
*/
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
/**
* 判断AbstractBeanFacotry工厂是否有父工厂(一般情况下是没有父工厂因为abstractBeanFactory直接是抽象类,不存在父工厂)
* 一般情况下,只有Spring 和SpringMvc整合的时才会有父子容器的概念,
* 比如我们的Controller中注入Service的时候,发现我们依赖的是一个引用对象,那么他就会调用getBean去把service找出来
* 但是当前所在的容器是web子容器,那么就会在这里的 先去父容器找
*/
BeanFactory parentBeanFactory = getParentBeanFactory();
//若存在父工厂,切当前的bean工厂不存在当前的bean定义,那么bean定义是存在于父beanFacotry中
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//获取bean的原始名称
String nameToLookup = originalBeanName(name);
//若为 AbstractBeanFactory 类型,委托父类处理
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// 委托给构造函数 getBean() 处理
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// 没有 args,委托给标准的 getBean() 处理
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
/**
* 方法参数 typeCheckOnly ,是用来判断调用 #getBean(...) 方法时,表示是否为仅仅进行类型检查获取 Bean 对象
* 如果不是仅仅做类型检查,而是创建 Bean 对象,则需要调用 #markBeanAsCreated(String beanName) 方法,进行记录
*/
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
/**
* 从容器中获取 beanName 相应的 GenericBeanDefinition 对象,并将其转换为 RootBeanDefinition 对象
* <bean id="xxx" class="com.xxx.xxx.xxxClass" abstract="true">
<property name="xxx" ref="tulingComxxxpent"></property>
</bean>
<bean id="xxx" class="com.xxx.xxx.xxx" parent="xxx"></bean>
*/
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//检查当前创建的bean定义是不是抽象的bean定义
checkMergedBeanDefinition(mbd, beanName, args);
/**
*
* @Bean
public DependsA dependsA() {
return new DependsA();
}
@Bean
@DependsOn(value = {"dependsA"})
public DependsB dependsB() {
return new DependsB();
}
* 处理dependsOn的依赖(这个不是我们所谓的循环依赖 而是bean创建前后的依赖)
*/
//依赖bean的名称
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// <1> 若给定的依赖 bean 已经注册为依赖给定的 bean
// 即循环依赖的情况,抛出 BeanCreationException 异常
for (String dep : dependsOn) {
//beanName是当前正在创建的bean,dep是正在创建的bean的依赖的bean的名称
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//保存的是依赖 beanName 之间的映射关系:依赖 beanName - > beanName 的集合
registerDependentBean(dep, beanName);
try {
//获取depentceOn的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
//创建单例bean
if (mbd.isSingleton()) {
//把beanName 和一个singletonFactory 并且传入一个回调对象用于回调
//在getSingleton中会把Bean标记为正在创建 详细看下面getSingleton源码
// 注意:
//这里的getSingleton和上面的getSingleton不是同一个
sharedInstance = getSingleton(beanName, () -> {
try {
//进入创建bean的逻辑 下面查看createBean()方法逻辑
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
//创建bean的过程中发生异常,需要销毁关于当前bean的所有信息
destroySingleton(beanName);
throw ex;
}
});
bean = 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);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
final 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, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
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",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
Copy the code
The getSingleton() method gets a singleton (this is not the same as the getSingleton method below)
The answer to this question is: yes, but it does not scale well…….
Reason: Obtaining the tertiary cache —–getEarlyBeanReference() goes through a series of post-processing to specialization our earlier objects
// When a wrapper object is fetched from the tertiary cache, it goes through a post-processor processing of our earlier object’s bean
Specialized processing, but Spring’s native post-processor is left untreated and left to developers to extend
singletonObject = singletonFactory.getObject();
Migrate the level 3 cache to the level 2 cache
this.earlySingletonObjects.put(beanName, singletonObject);
// Delete from level 3 cache
this.singletonFactories.remove(beanName);
/** * @param allowEarlyReference specifies whether to allow exposure of early objects It may return a NULL (when the IOC container loads a singleton bean, it returns NULL the first time) * it may return a singleton object (when the IOC container loads a singleton, it fetches the current bean a second time) * or it may return an earlier object (to solve the loop dependency problem) */ @Nullable protected Object getSingleton(String beanName, Boolean allowEarlyReference) {/** * Step 1: We try to go to level 1 cache (singleton cache pool, usually from this map objects are directly available) * IOC container initialization load singleton bean when first come in The map in the general returns an empty * / Object singletonObject = this. SingletonObjects. Get (beanName); / * * * if no get to the object, in the first level cache and singletonsCurrentlyInCreation this list contains the initialization beanName * IOC container loading single instance bean come in for the first time The average returns an empty list, but circular dependencies can satisfy the conditions * / if (singletonObject = = null && isSingletonCurrentlyInCreation (beanName)) {synchronized (this.singletonObjects) {/** * Attempts to fetch an object from the secondary cache (the secondary cache object is an early object) Could give the property of the bean assignment objects (pure) * is early object * / singletonObject = this. EarlySingletonObjects. Get (beanName); If (singletonObject == null && allowEarlyReference) {/** * Fetch ObjectFactory objects directly from the level 3 cache. This docking is the key to getting around circular dependencies * In the late IOC process, when the bean calls the constructor, the early object is wrapped as an ObjectFactory * and exposed to the level 3 cache */ ObjectFactory<? > singletonFactory = this.singletonFactories.get(beanName); If (singletonFactory! = null) {/** * here we get our earlier object by calling its getObject() from the exposed ObjectFactory wrapper object * this section calls getEarlyBeanReference() for post-processing */ singletonObject = singletonFactory.getObject(); / / the early object placed in the second level cache, enclosing earlySingletonObjects. Put (beanName singletonObject); / / the ObjectFactory packaging object is removed from the l3 cache off this. SingletonFactories. Remove (beanName); } } } } return singletonObject; }Copy the code
GetSingleton ()(this is not the same method as above)
public Object getSingleton(String beanName, ObjectFactory<? > singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); Synchronized (this.singletonObjects) {// Try to obtain the Object singletonObject from the singleton cache pool 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 + "'"); } / * * * mark the current bean is created soon * singletonsCurrentlyInCreation will add beanName to come in here, If the second loop depends (constructor injection throws an exception) */ beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try {//<3> initialize the bean // this process actually calls createBean() method // getSingleton above passes in an ObjectFactory function interface where the callback singletonObject = is made singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) {// Call back to our singletonObjects get method to create the bean logic 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; } / / / / rear < 4 > processing mainly do is to put the singletonsCurrentlyInCreation tag is creating bean removed from the collection afterSingletonCreation (beanName); } if (newSingleton) {// <5> addSingleton(beanName, singletonObject) to the cache; } } return singletonObject; }} /** * Add the object to the singleton cache pool (so-called level 1 cache and take into account loop dependencies and normally remove the second and third caches) * @param beanName bean name * @param singletonObject created singleton bean */ protected void addSingleton(String beanName, Object singletonObject) {synchronized (enclosing singletonObjects) {/ / join the singleton cache pool this. SingletonObjects. Put (beanName, singletonObject); / / removed from the l3 cache (for not dealing with circular dependencies) enclosing singletonFactories. Remove (beanName); / / removed from the second level cache (circular dependencies Early object exists in the second level cache) enclosing earlySingletonObjects. Remove (beanName); / / used to process the bean record keeping is enclosing registeredSingletons. Add (beanName); }}Copy the code
The createBean() method creates the bean
@Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; Class<? > resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass ! = null && ! mbd.hasBeanClass() && mbd.getBeanClassName() ! = null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. Try {/** * Validate and Prepare override methods (only in XML mode) * lookup-method and replace-method * MethodOverrides in BeanDefinition (only in XML mode) * If methodOverrides are detected during bean instantiation in XML mode, * dynamically generates a proxy for the current bean and uses the corresponding interceptor to enhance the bean. * specific implementation subsequent analysis, we now see mbdToUse. First prepareMethodOverrides () code block * / mbdToUse prepareMethodOverrides (); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try {/** * the first bean postprocessor generates a proxy object by postprocessing the bean's postprocessor, which is normally not generated here * why not generate a proxy object, neither our JDK proxy nor the cglib proxy does it here, Since our * real objects are not generated, proxy objects will not be generated here, so this is the key for our AOP and transactions at this step, Because here * parsing our aop caching section information detailed view resolveBeforeInstantiation source * * * / Object bean = resolveBeforeInstantiation (beanName, mbdToUse); if (bean ! = null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } beanInstance = doCreateBean(beanName, beanName, beanInstance); mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("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); }}Copy the code
ResolveBeforeInstantiation method
@Nullable protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (! Boolean. FALSE. Equals (MBD) beforeInstantiationResolved)) {/ / whether the container is InstantiationAwareBeanPostProcessors if (! MBD. IsSynthetic () && hasInstantiationAwareBeanPostProcessors ()) {/ / get the current bean class object class <? > targetType = determineTargetType(beanName, mbd); if (targetType ! = null) {/** * there are a total of nine times that a transaction will not be called before aop is called. Because here need to parse out the cut surface of the corresponding error to the cache * * see attached applyBeanPostProcessorsBeforeInstantiation method call post processor * / bean = source applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); / / rear InstantiationAwareBeanPostProcessors processor postProcessBeforeInstantiation returns if not null / / that generates a proxy object then we will call the if (bean! = null) {/** * the second call to the post-handler, if the post-handler is called, So the first processor must return not null postProcessAfterInitialization * * rear InstantiationAwareBeanPostProcessors processor/bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean ! = null); } return bean; }Copy the code
Rear applyBeanPostProcessorsBeforeInstantiation processor calls
@Nullable protected Object applyBeanPostProcessorsBeforeInstantiation(Class<? > beanClass, String beanName) {/** * get all the processors in the container */ for (BeanPostProcessor bp: GetBeanPostProcessors ()) {/ / figure out whether post processor InstantiationAwareBeanPostProcessor / / will directly return to bean stop create AOP if (bp) instanceof InstantiationAwareBeanPostProcessor) {/ / our BeanPostProcessor forced into InstantiationAwareBeanPostProcessor InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; / * * * * important 】 【 we AOP @ EnableAspectJAutoProxy container import AnnotationAwareAspectJAutoProxyCreator * for us Our transaction annotations @ EnableTransactionManagement for our container imports the InfrastructureAdvisorAutoProxyCreator * are realized our BeanPostProcessor interface, InstantiationAwareBeanPostProcessor, * rear processing analytical aspects * / Object result = ibp. PostProcessBeforeInstantiation (beanClass, beanName); if (result ! = null) { return result; } } } return null; }Copy the code
DoCreateBean source
This completes the four main stages of Bean creation described in the previous article: instantiation, property population, initialization, and destruction.
/** * This method is the most complex of its kind. It contains calls to constructors, assigns values to bean properties, calls to bean initializers, and generates proxy objects Definition of bean * @param args passed arguments * @return instance of bean * @throws BeanCreationException if the bean could not be created * @see #instantiateBean * @see #instantiateUsingFactoryMethod * @see #autowireConstructor */ protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Final @Nullable Object[] args) throws BeanCreationException {//BeanWrapper is a wrapper for beans. The function defined in the interface is very simple, including setting the Object to be wrapped, BeanWrapper instanceWrapper = null; If (MBD) isSingleton ()) {/ / removed from the of unfinished FactoryBean instanceWrapper = this. FactoryBeanInstanceCache. Remove (beanName); } if (instanceWrapper == null) {// Create bean instantiation to create a new instance using the appropriate instantiation strategy: InstanceWrapper = createBeanInstance(beanName, MBD, args); } / / to get our early objects from the beanWrapper / / here have the Object, but the inside of the Object attribute is empty, haven't to assign the final 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 {/ / rear processing @autowired @ the annotation of the Value of preliminary analytical applyMergedBeanDefinitionPostProcessors (MBD, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; }} /** * caches singletons to the level 3 cache in case the loop depends on the Bean to determine whether it can be referenced earlier, and if so, allows the reference to be exposed early to determine whether the earlier object can be exposed: * whether singleton * whether to allow circular dependencies are * create Bean * / Boolean earlySingletonExposure = (MBD) isSingleton () && enclosing allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); // If the above conditions are met, If (earlySingletonExposure) {if (logger.isDebugenabled ()) {logger.debug(" Gbit/s caching bean '" + beanName + "' to allow for resolving potential circular references"); } // Wrap our earlier object as a singletonFactory object that provides a getObject method that internally calls the getEarlyBeanReference method addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; Try {// Assign the property to our property (call the set method to assign the value) // Also call a lot of the post-processor 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) {** * get our object from the cache because the allowEarlyReference passed is false */ Object earlySingletonReference = getSingleton(beanName, false); If (earlySingletonReference! If (exposedObject == bean) {exposedObject == bean earlySingletonReference; } // Process the dependent bean 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 " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); }}}} / / Register beans as the disposable. Try {/ / registered destruction destruction of bean interface registerDisposableBeanIfNecessary (beanName, bean, MBD); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }Copy the code
InitializeBean () method
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() ! = null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else {// If our bean implements the XXXAware interface for the method callback // the source code behind this block is invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || ! MBD. IsSynthetic ()) {/ / call our bean postProcessorsBeforeInitialization method of post processor @ PostCust wrappedBean = annotation methods applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try {// invokeInitMethods(beanName, wrappedBean, MBD); } catch (Throwable ex) { throw new BeanCreationException( (mbd ! = null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || ! MBD. IsSynthetic ()) {/ / call us beans rear processor PostProcessorsAfterInitialization method wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; } / / here will only call three class implements Aware method / / other would call in ApplicationContextAwarePostProcess private void invokeAwareMethods (final String beanName, Final Object bean) {if (BeanNameAware) {// Our bean implements BeanNameAware if (BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); If (bean instanceof BeanClassLoaderAware) {ClassLoader BCL = getBeanClassLoader(); if (bcl ! = null) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } // Implement BeanFactoryAware if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); }}}Copy the code
The above is SpringIOC’s loading process source code analysis process, which also has a lot of details designed, can not be listed one by one, just list a general loading process, specific details, you can go to view the source code.