Spring start basically see AbstractBeanFactory. Refresh method
public void refresh() throws BeansException, IllegalStateException { .... // A template method allows subclasses to implement postprocessing postProcessBeanFactory(beanFactory); // A template method allows subclasses to implement postprocessing postProcessBeanFactory(BeanFactory); / / call the beanfactory invokeBeanFactoryPostProcessors processor (the beanfactory); / / register beans rear processor beanpostprocessor registerBeanPostProcessors (the beanFactory); // Initialize the message source initMessageSource(); / / initialize the application actual events entrusted initApplicationEventMulticaster released (); // A template method subclass implements a specific refresh method onRefresh(); // Check listeners and register registerListeners(); / / instantiate all the lazy loading simple interest bean. FinishBeanFactoryInitialization (the beanFactory); // Publish the corresponding event finishRefresh(); }... }Copy the code
Create Bean object is in finishBeanFactoryInitialization approach
Protected void finishBeanFactoryInitialization (ConfigurableListableBeanFactory the beanFactory) {/ / do some initialization code here ready to work... / / cache beanDefinitionName the beanFactory. FreezeConfiguration (); / / instantiate all the lazy loading singleton. The beanFactory preInstantiateSingletons (); }Copy the code
Let’s look at the actual creation method
Public void preInstantiateSingletons() throws BeansException {// Get all registered beanNames List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Initialize all non-lazy loaded beans for (String beanName: BeanNames) {/ / bean definition information RootBeanDefinition bd = getMergedLocalBeanDefinition (beanName); // If the object is not abstract and is a singleton and not lazily loaded, enter the method if (! bd.isAbstract() && bd.isSingleton() && ! Bd.islazyinit ()) {if (isFactoryBean(beanName)) {bd.islazyInit ()) { } else {// Create the bean object getBean(beanName); }}}}Copy the code
First, get the names of all registered beans, then go through all beanName, get the bean definition information (beanDefinition stores the basic information of bean, including whether singleton, lazy loading, etc.), determine whether the object is a normal bean object. Then go see next AbstractBeanFatory getBean method, call a doGetBean method, it is well known is the work of introduction of spring inside the do…
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
Copy the code
There are two classes A and B depend on each other, first create A object Then see AbstractBeanFatory doGetBean method, look at the overall flow, behind the analysis one by one
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; Object sharedInstance = getSingleton(beanName); if (sharedInstance ! = null && args == null) { ... // bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else {/ / if the prototype pattern is being created and will throw an exception if (isPrototypeCurrentlyInCreation (beanName)) {throw new BeanCurrentlyInCreationException(beanName); } // getParentBeanFactory = getParentBeanFactory(); // If no bean definition information exists, try to get if (parentBeanFactory! = null && ! containsBeanDefinition(beanName)) { ... }} // If not type check if (! TypeCheckOnly) {// Mark the bean to create or to create markBeanAsCreated(beanName); } the try {/ / bean definition information final RootBeanDefinition MBD = getMergedLocalBeanDefinition (beanName); / / check bean information checkMergedBeanDefinition (MBD, beanName, args); String[] dependsOn = mbd.getSon (); if (dependsOn ! = null) {// Dependon creates for (String dep: DependsOn) {// Determine whether to depend -on if (isDependent(beanName, dep)) {... } registerDependentBean(dep, beanName); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { ... If (mbd.issingleton ()) {// call the getSingleton method, SharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName,) mbd, args); } catch (BeansException ex) { ... }}); Bean = getObjectForBeanInstance(sharedInstance, name, beanName, MBD); Else if (mbd.isprototype ()) {... } // other modes create else {... } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; If (requiredType! = null && ! requiredType.isInstance(bean)) { ... } return (T) bean; }Copy the code
First see DefaultSingletonBeanRegistry. The getSingleton method 1. SingletonObjects: first-level cache, deposit the full bean 2. EarlySingletonObjects: SingletonFactories: The third level cache holds an ObjectFactory generation bean
protected Object getSingleton(String beanName, Boolean allowEarlyReference) {/ / to get objects from level 1 cache Object singletonObject = this. SingletonObjects. Get (beanName); / / the singleton and not be created if (singletonObject = = null && isSingletonCurrentlyInCreation (beanName)) {synchronized (this singletonObjects) {/ / level 2 cache singletonObject = this. EarlySingletonObjects. Get (beanName); If (singletonObject == null && allowEarlyReference) {// > singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory ! L3 cache = null) {/ / call getObject method, this way is a lambda expressions, later analysis singletonObject = singletonFactory. GetObject (); / / put objects in the second level cache enclosing earlySingletonObjects. Put (beanName singletonObject); / / clean up level 3 this cache. SingletonFactories. Remove (beanName); } } } } return singletonObject; }Copy the code
. Then look at the second important way DefaultSingletonBeanRegistry getSingleton method, here I omitted some logging and exception
public Object getSingleton(String beanName, ObjectFactory<? Synchronized (this.singletonObjects) {synchronized (this.singletonObjects) {synchronized (this.singletonObjects) this.singletonObjects.get(beanName); if (singletonObject == null) { if (this.singletonsCurrentlyInDestruction) { ... }... // Check beforeSingletonCreation(beanName) before creating the object; boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } the try {/ / walk just incoming lambda expressions singletonObject = singletonFactory. GetObject (); newSingleton = true; } catch (IllegalStateException ex) { singletonObject = this.singletonObjects.get(beanName); . } catch (BeanCreationException ex) { ... } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } // Check afterSingletonCreation(beanName) after creating the bean; } if (newSingleton) {// addSingleton(beanName, singletonObject); } } return singletonObject; }}Copy the code
Now look at the getObject method
SharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, MBD, args); } catch (BeansException ex) { ... }});Copy the code
Call the AbstractAutowireCapableBeanFactory createBean method
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { ... RootBeanDefinition mbdToUse = mbd; . Class<? Class<? > resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass ! = null && ! mbd.hasBeanClass() && mbd.getBeanClassName() ! = null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); Prepares and rewriting method} / / there is no overrides the spring but have / / lookup - method, and the replace method need to parse the try {mbdToUse. PrepareMethodOverrides (); } catch (BeanDefinitionValidationException ex) { ... } try {/ / return a proxy Object instead of the real instance, the Object is instantiated before operation bean = resolveBeforeInstantiation (beanName mbdToUse); if (bean ! = null) { return bean; } } catch (Throwable ex) { ... } try {beanInstance = doCreateBean(beanName, mbdToUse, args); return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { ... } catch (Throwable ex) { ... }}Copy the code
Look at one of the two methods the first method AbstractAutowireCapableBeanFactory. ResolveBeforeInstantiation method, before the object can generate proxy object returns, as follows:
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (! Boolean. FALSE. Equals (MBD) beforeInstantiationResolved)) {/ / judgment is defined outside of this class, and instantiate the rear processor if (! MBD. IsSynthetic () && hasInstantiationAwareBeanPostProcessors ()) {/ / access to the target object Class <? > targetType = determineTargetType(beanName, mbd); if (targetType ! = null) {/ / go to instantiate the rear processor bean = applyBeanPostProcessorsBeforeInstantiation (targetType, beanName); if (bean ! = null) {/ / go to initialize post processor bean = applyBeanPostProcessorsAfterInitialization (bean, beanName); Whether}}} / / tag parsed MBD. BeforeInstantiationResolved = (bean! = null); } return bean; }Copy the code
Look at the rear instantiation processing logic processor AbstractAutowireCapableBeanFactory. ApplyBeanPostProcessorsBeforeInstantiation method:
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<? > beanClass, String beanName) {// For (BeanPostProcessor bp: GetBeanPostProcessors ()) {/ / if it is such a subclass of entering the if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; / rear/execution processor to realize the instantiation of the Object before processing method result = ibp. PostProcessBeforeInstantiation (beanClass, beanName); if (result ! = null) { return result; } } } return null; }Copy the code
Initialize the post processor AbstractAutowireCapableBeanFactory applyBeanPostProcessorsAfterInitialization method, logical basic and before the instantiation of the rear handler method just don’t see the same side. If there is nothing special to do then go to the normal doCreateBean method. First look at the general process:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) {// Instantiate the object instanceWrapper = createBeanInstance(beanName, MBD, args); } final Object bean = instanceWrapper.getWrappedInstance(); Class<? > beanType = instanceWrapper.getWrappedClass(); if (beanType ! = NullBean.class) { mbd.resolvedTargetType = beanType; Synchronized (mbd.postProcessingLock) {if (! mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { ... } mbd.postProcessed = true; }} // Check whether singletons allow circular dependencies on objects being created, If it is for a tag is exposed in the three-level cache Boolean earlySingletonExposure = (MBD) isSingleton () && enclosing allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { ... // Put yourself in level 3 cache, AddSingletonFactory (beanName, () -> getEarlyBeanReference(beanName, MBD, bean)); } Object exposedObject = bean; // Assign the property populateBean(beanName, MBD, instanceWrapper); // Initialize the object exposedObject = initializeBean(beanName, exposedObject, MBD); } catch (Throwable ex) { ... } if (earlySingletonExposure) {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()) { ... }}}} / / at the factory, if necessary can be discarded bean list sign-up try {registerDisposableBeanIfNecessary (beanName, bean, MBD); } catch (BeanDefinitionValidationException ex) { ... } return exposedObject; }Copy the code
Main method of several key first look AbstractAutowireCapableBeanFactory. ApplyMergedBeanDefinitionPostProcessors method:
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<? > beanType, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof MergedBeanDefinitionPostProcessor) { MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName); }}}Copy the code
Can see is to obtain all the post processor, and then find MergedBeanDefinitionPostProcessor subclasses, and then execute the subclass methodsWe’ll analyze it after we deal with the details. Next, look at the populateBean method, which is the method for injecting properties, where configuration files and Autowired are handled
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { ... boolean continueWithPropertyPopulation = true; // execute the instantiated post-handler if (! mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { ... } } if (! continueWithPropertyPopulation) { return; PVS = (mbd.haspropertyValues ()? mbd.getPropertyValues() : null); if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); / / in accordance with the name assignment if (MBD getResolvedAutowireMode () = = AUTOWIRE_BY_NAME) {autowireByName (beanName, MBD, bw, newPvs); } / / if according to the type of assignment (MBD) getResolvedAutowireMode () = = AUTOWIRE_BY_TYPE) {autowireByType (beanName, MBD, bw, newPvs); } pvs = newPvs; } / / post processor has instantiated Boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors (); Boolean needsDepCheck = (mbd.getDependencyCheck()! = AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { if (pvs == null) { pvs = mbd.getPropertyValues(); } / / filtered property description information PropertyDescriptor [] filteredPds = filterPropertyDescriptorsForDependencyCheck (bw, MBD. AllowCaching); If (hasInstAwareBpps) {// Iterate through the afterprocessor for (BeanPostProcessor bp: getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; / / go to instantiate the post processor PVS = ibp postProcessPropertyValues method. The postProcessPropertyValues (PVS, filteredPds, bw. GetWrappedInstance (), beanName); if (pvs == null) { return; }}}} if (needsDepCheck) {check checkDependencies(beanName, MBD, filteredPds, PVS); } } if (pvs ! = null) {applyPropertyValues(beanName, MBD, bw, PVS); }}Copy the code
Properties of AutowiredAnnotationBeanPostProcessor. PostProcessPropertyValues is autowired value assignment method
public PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {// InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); Inject (bean, beanName, PVS); } catch (Exception ex) { .. } return pvs; }Copy the code
Process is long, basically see AutowiredAnnotationBeanPostProcessor. Inject method, red box marked place is solution to rely onIf you go into this method, you’ll see the familiar do approach, which is how you actually get things startedThere are a lot of judgment and preparation work in the process, which is a little long, so there is no demonstration here. Interested partners can have a look by themselves, and directly pay attention to the following method after entering the methodThis method is used to create DependencyDescriptor objects, where desriptor is a DependencyDescriptor object. If you enter this object’s resolveCondidate method, you can see the familiar method:A getBean method, so we start the process of creating B objects again. When getSingleton gets the object, the ObjectFactory object stored by A can be queried in the level 3 cache. This object then calls its own getObject() method. This method is the lambda expression method passed in earlier.Then analyze the AbstractAutowireCapableBeanFactory getEarlyBeanReference method, familiar with operation
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; if (! MBD. IsSynthetic () && hasInstantiationAwareBeanPostProcessors ()) {/ / to iterate through all the post processor for (BeanPostProcessor bp: GetBeanPostProcessors ()) {/ / find SmartInstantiationAwareBeanPostProcessor subclasses of the if (bp) instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; / / execution subclass methods exposedObject = ibp. GetEarlyBeanReference (exposedObject, beanName); } } } return exposedObject; }Copy the code
Can see SmartInstantiationAwareBeanPostProcessor subclass, contains the Aop processing class
So in circular dependencies, aop is done when the object is created out of the tertiary cache and some other post-processor operations are done to analyze the AbstractautoxyCreator’s getEarlyBeanReference method, which marks the object as an early proxy reference before calling it. That is, to remind the object that it has been enhancedThe abstractautoXyCreator initialization postprocess will determine if it has been aop enhanced because of loop dependenciesThe getEarlyBeanReference calls the wrapIfNecessary method
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { ... Some / / merge all need to intercept enhanced and collates the Object [] specificInterceptors = getAdvicesAndAdvisorsForBean (bean. GetClass (), beanName, null); if (specificInterceptors ! = DO_NOT_PROXY) {this.AdvisedBeans.put (cacheKey, boolea.true); Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } // This. Advisedbeans. put(cacheKey, Boolea.false); return bean; }Copy the code
Generating proxy objects and how to merge enhanced objects without analyzing this time, after getObject we go back to the getSingleton method we just did, and then put the object into the secondary cache and delete the tertiary cacheIt then returns the created object, in which case B is a complete Bean object. After B is created, it will put itself into the level 1 cache and then empty the level 2 and 3 caches
Then we go back to the creation of the A object, at which point the attribute assignment is finished and the Bean object is initialized. As you can see, the various Aware methods are determined first, followed by the initialization preprocessing, followed by the invokeInitMethodThe ps: @postConstruct annotation is superior to afterPropertiesSet and init-methodAfter executing the post-processor, the object is fetched from level 2 or level 3 cache.Finally, put the object into the level-1 cache and clear the level-2, level-3 cache.
A: The proxy object refers to the original object, so the proxy object is created first and then assigned to the original object. The proxy object is also updated synchronously.