This time, understand the bean instantiation principle of spring

Don't talk at night 2022-02-13 07:27:05 阅读数:202

time understand bean instantiation principle

Preface

The first two articles analyzed Spring XML Analysis principle of and annotation , And encapsulate it as BeanDefinition Objects stored in IOC In the container , And these are just refresh One of the steps in the method ——obtainFreshBeanFactory, Then we will focus on these BeanDefinition Object performs a series of processing , Such as BeanDefinitionRegistryPostProcessor Object method call 、BeanFactoryPostProcessor Call of object method and Bean The creation of instances is inseparable from these BeanDefinition object . So let's see Spring How are these objects handled .

Text

Environmental preparation

First, let's recall refresh Method :

 public void refresh() throws BeansException, IllegalStateException {

synchronized (this.startupShutdownMonitor) {

// Prepare for container initialization 
prepareRefresh();
// analysis xml Annotation 
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// to BeanFacory Set property values and add some processors , Ready Spring Context of 
prepareBeanFactory(beanFactory);
try {

// The subclass implements a pair of BeanFacoty Some post-processing of 
postProcessBeanFactory(beanFactory);
/* * BeanDefinitionRegistryPostProcessor * BeanFactoryPostProcessor * Complete the call to these two interfaces * */
invokeBeanFactoryPostProcessors(beanFactory);
/* * To achieve BeanPostProcessor Class instantiation of interface , And join in BeanFactory in * */
registerBeanPostProcessors(beanFactory);
/* * internationalization * */
initMessageSource();
// Initialize the event management class 
initApplicationEventMulticaster();
// This approach focuses on understanding template design patterns , Because in springboot in , This method is used for embedding tomcat Starting up 
onRefresh();
/* * Register the event class in the event management class * */
registerListeners();
/* * 1、bean Instantiation process * 2、 Dependency injection * 3、 Annotation support * 4、BeanPostProcessor Implementation * 5、Aop Entrance * * */
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
} finally {

resetCommonCaches();
}
}
}

prepareBeanFactory and postProcessBeanFactory Nothing complicated , Pay attention to what values are set in it , Just add the objects , These things will play a role in the later process . In especial postProcessBeanFactory, This is a template method , In its subclass AbstractRefreshableWebApplicationContext Two important signs are set in :

 protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {

// Mainly look inside 
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {

Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// Remove from old position, if any
this.beanPostProcessors.remove(beanPostProcessor);
// Track whether it is instantiation/destruction aware
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {

this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {

this.hasDestructionAwareBeanPostProcessors = true;
}
// Add to end of list
this.beanPostProcessors.add(beanPostProcessor);
}

Separately hasInstantiationAwareBeanPostProcessorshasDestructionAwareBeanPostProcessors The properties are set to true, Guess what they do .

Two important Processor

After setting the context , It is through invokeBeanFactoryPostProcessors Method complete right BeanDefinitionRegistry as well as BeanFactory Post processor processing and calling , That is, call in turn BeanDefinitionRegistryPostProcessor Interface and BeanFactoryPostProcessor Implementation class of interface . We can implement these two interfaces in stay BeanDefinition After registration , Before object instantiation For... In the container BeanDefinition Add, delete, check and modify dynamically , such as Spring in @Configuration Annotation parsing is implemented in this process . So let's see Spring Built in Processor What is the implementation : Insert picture description here
The whole system needs to have a general impression , It focuses on ConfigurationClassPostProcessor class , This class is to complete @Configuration、@Bean And other annotations , The source code of this piece will not be analyzed here for the time being . Continue the process you started , Enter into invokeBeanFactoryPostProcessors Method :

 protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {

// getBeanFactoryPostProcessors Methods generally can't get the value , Unless we manually call addBeanFactoryPostProcessor Method to add ,
// In other words, we can annotate @Component Or manually call addBeanFactoryPostProcessor Method to inject BeanFactoryPostProcessors object 
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
Omit ......
}

Inside this adopt Delegate pattern call PostProcessorRegistrationDelegate Of invokeBeanFactoryPostProcessors Method , And passed in BeanFactory and Processors object , But we need to pay attention getBeanFactoryPostProcessors The method is not to get through xml To configure and Component Annotations are registered in the container Processor object , Instead, get through the call AbstractApplicationContext.addBeanFactoryPostProcessor Method , In other words, we achieved Processor Interface can not be added to the class @Component, Call directly addBeanFactoryPostProcessor The method can , But we need to pay attention , There is no corresponding in this way BeanDefinition class , The added object does not exist in IOC In the container .
Continue to enter invokeBeanFactoryPostProcessors Method :

 public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {

BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// Give priority to passing addBeanFactoryPostProcessor Method BeanFactoryPostProcessor
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {

// priority BeanDefinitionRegistryPostProcessor object 
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {

BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {

regularPostProcessors.add(postProcessor);
}
}
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// Acquisition realizes BeanDefinitionRegistryPostProcessor Of all classes of the interface BeanDefinition Object's beanName
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {

// Determine whether the sorting interface is implemented PriorityOrdered
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {

currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// Sort 
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// Call the process 
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {

// Determine whether it is implemented Ordered Interface 
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {

currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// The call of sorting interface is not implemented 
boolean reiterate = true;
while (reiterate) {

reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {

if (!processedBeans.contains(ppName)) {

currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// call postProcessBeanFactory Method 
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {

// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Acquisition realizes BeanFactoryPostProcessor The class of the interface , obtain beanDefinition The name of 
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {

if (processedBeans.contains(ppName)) {

// skip - already processed in first phase above
}
// Realized PriorityOrdered Interface 
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {

priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
// Realized Ordered Interface 
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {

orderedPostProcessorNames.add(ppName);
}
else {

// There is no interface 
nonOrderedPostProcessorNames.add(ppName);
}
}
// Sort 
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// call 
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {

orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {

nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
beanFactory.clearMetadataCache();
}

It's a long way , But the logic is not complicated . First, judge the incoming BeanFactory Is the object BeanDefinitionRegistry object , If yes, call the incoming first Processor Object's postProcessBeanDefinitionRegistry Method , After that beanFactory.getBeanNamesForType Get all the... In the container BeanDefinitionRegistryPostProcessor The name of the implementation class , Then instantiate and call the implementation in turn PriorityOrderedOrdered Interface ( The former has priority over the latter , The smaller the number, the higher the priority ) Of Processor Of postProcessBeanDefinitionRegistry Method , The remaining interfaces that are not instantiated are called and re implemented Processor Methods . When all BeanDefinitionRegistryPostProcessor After the implementation class call is completed , Will call from the parent interface in turn BeanFactoryPostProcessor Of postProcessBeanFactory Method .
After the above process is completed , It'll go through again beanFactory.getBeanNamesForType Get all the... In the container BeanFactoryPostProcessor The name of the implementation class , The process is the same as above .

register BeanPostProcessor object

The above is the calling process of the two extension points , After completion, it will call registerBeanPostProcessors Register all BeanPostProcessor Subclasses of into the container , This interface is also Spring An important extension point of , It contains two methods :

 @Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

return bean;
}

The object that implements the interface will call these two methods before and after instantiation . Again , Let's first understand the inheritance system of the interface :
 Insert picture description here
You can see this interface Spring There are many built-in implementations , It can be seen that it is widely used . In addition, the red box above is the class that needs to be remembered this time , Back Bean When instantiating, there will be . Then let's take a look at registerBeanPostProcessors The implementation logic of :

 public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

// Get everything in the project and realize BeanPostProcessor The class of the interface , Get BeanDefinition The name of 
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// Instantiate ahead of time BeanPostProcessor Type of bean, then bean Sort 
for (String ppName : postProcessorNames) {

if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {

//getBean Is an instantiation method , Later we will talk about bean The instantiation process will focus on 
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
// Determine whether the type is MergedBeanDefinitionPostProcessor, If so, the code is used internally 
if (pp instanceof MergedBeanDefinitionPostProcessor) {

internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {

orderedPostProcessorNames.add(ppName);
}
else {

nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Sign up to BeanFactory in 
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {

BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {

internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {

BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {

internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

The implementation logic of this code is also very simple , Also prioritize first , Get more Bean example , Finally register in the container , wait until Bean Call... When instantiating .
The next in refresh Method is called initMessageSourceinitApplicationEventMulticasteronRefreshregisterListeners, Namely Initialize international resources Initialize the time broadcaster Container refresh Events ( Subclass callback ) Register listener , These methods are very simple , Just look for yourself , I won't go into details here .

Bean Object creation

When all the preparations are done , It's time to start initializing Bean The instance , That is to say finishBeanFactoryInitialization What method does . But this is not the basis BeanDefinition new One object is over , It contains the following work :

  • Initialize instance
  • analysis @PostConstruct,@PreDestroy,@Resource, @Autowired,@Value Etc
  • Dependency injection
  • call BeanPostProcessor Method
  • AOP entrance ( This article will not analyze )

Here's a detailed analysis Bean The whole process of instantiation :

 protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {

......
// Focus on this method 
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
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.
// xml When parsing , I told you , Put all the beanName All cache to beanDefinitionNames 了 
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {

// The father BeanDefinition The attributes in it BeanDefinition in 
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// If it's not abstract , The singleton , Instantiation without lazy loading 
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {

// Judge bean Is it implemented FactoryBean Interface , You don't have to watch it here 
if (isFactoryBean(beanName)) {

Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {

final 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);
}
}
}
else {

// Mainly enter from here , Look at the instantiation process 
getBean(beanName);
}
}
}
}

stay preInstantiateSingletons As you can see in the method, there is a judgment : Single case Non lazy loading Non Abstract , Only when these three conditions are met can it be called getBean(Bean Instantiation is achieved by calling this method ) Instantiation :

 public Object getBean(String name) throws BeansException {

return doGetBean(name, null, null, false);
}
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);
System.out.println("====beanName=="+beanName+"===instance begin====");
Object bean;
// Get an instance from the cache 
Object sharedInstance = getSingleton(beanName);
// If you can get an instance in the cache 
if (sharedInstance != null && args == null) {

// The method is FactoryBean Interface call entry 
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {

// If there is no... In the cache , Then walk down 
// If it is scope yes Prototype Of , Check whether there is circular dependency , If there is any error, it will be reported directly 
if (isPrototypeCurrentlyInCreation(beanName)) {

throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {

// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {

return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {

// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {

// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {

return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {

markBeanAsCreated(beanName);
}
try {

// Father and son BeanDefinition Merge 
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// Check whether it is an abstract class , Is to throw an exception directly 
checkMergedBeanDefinition(mbd, beanName, args);
// Get dependent object properties , Dependent objects must be instantiated first 
// 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)) {

throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {

// Instantiation 
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {

throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Most of them are single cases 
if (mbd.isSingleton()) {

sharedInstance = getSingleton(beanName, () -> {

try {

return createBean(beanName, mbd, args);
}
});
// The method is FactoryBean Interface call entry 
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);
}
// The method is FactoryBean Interface call entry 
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);
}
});
// The method is FactoryBean Interface call entry 
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
}
}
}
return (T) bean;
}

This code first gets the singleton object from the cache , without , Through scope Type to create the corresponding Bean example ( Create directly or through getObjectForBeanInstance call FactoryBean Interface method creation ). Before creating an object, if scope yes prototype Type will pass first isPrototypeCurrentlyInCreation Check for the presence of Cyclic dependence ( Circular dependency is not discussed here ), There are exceptions thrown directly , Prototype object Circular dependencies are not allowed ; After verification, it will pass mbd.getDependsOn Get @DependsOn The value of the annotation , If there is , The dependent objects will be instantiated first .
Because most of them create singleton objects , So I'll take getSingleton Method to analyze , Note that this method passes in a Lambda expression , Called in the expression createBean Method , Observe other scope establish bean You will find that the method is called , So actually create bean Object is the method , But let's go first getSingleton Method to see what has been done :

 public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {

Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {

// If there is , Then return directly 
Object singletonObject = 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 + "'");
}
// hold beanName Add to singletonsCurrentlyInCreation Set In the container , In this collection bean Are instantiating bean
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {

this.suppressedExceptions = new LinkedHashSet<>();
}
try {

// If there is a return value here , On behalf of this bean Has finished creating , Created completely 
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
finally {

if (recordSuppressedExceptions) {

this.suppressedExceptions = null;
}
//bean After creation singletonsCurrentlyInCreation To delete this bean
afterSingletonCreation(beanName);
}
if (newSingleton) {

System.out.println("====beanName==" + beanName + "===instance end====");
// When the object is created successfully , Cache objects to singletonObjects In cache ,bean When the creation is completed, put it into the L1 cache 
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}

In this method, the first thing is to get the object from the cache , If there is a direct return , If not, the object's beanName Add to singletonsCurrentlyInCreation In cache , If the addition is unsuccessful , Indicates that the object is already being created elsewhere , Throw an exception directly when creating the current , If the addition is successful , Call singletonFactory.getObject To create an object , This method is passed in Lambda expression , Delete after creation singletonsCurrentlyInCreation Cache the value in the and add the object to the first level cache , When the object is needed later , Are obtained from the L1 cache .
stay getObject Pass through createBean To create an object , And the method calls doCreateBean, Let's look at this method directly :

 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {

// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {

instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {

// Create examples ,, The key to see 
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 {

// Bean Collect annotations in the class after instantiation (@PostConstruct,@PreDestroy,@Resource, @Autowired,@Value)
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {

throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Single case bean Exposure in advance 
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");
}
// Here we focus on understanding , It's very helpful to understand circular dependency , Add L3 cache 
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {

// ioc di, The core method of dependency injection 
populateBean(beanName, mbd, instanceWrapper);
// bean Instantiation +ioc Call after dependency injection 
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);
}
}
}
}
}
// Register bean as disposable.
try {

// register bean Class at destruction DisposableBeanAdapter
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
return exposedObject;
}

In this method, first pass createBeanInstance Create an instance of the object , After creation, it passes applyMergedBeanDefinitionPostProcessors Collect annotations in classes @Autowired、@Value、@PostConstruct,@PreDestroy,@Resource Prepare dependency injection or method call , Next call addSingletonFactory add to Three level cache Deal with circular dependencies , After through populateBean Dependency injection really completes Creation of a complete object , Last in initializeBean Medium trigger event and Some method calls . These methods are analyzed one by one .

createBeanInstance

 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {

// Make sure bean class is actually resolved at this point.
// The reflex gets Class object 
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {

throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {

return obtainFromSupplier(instanceSupplier, beanName);
}
// stay xml To configure bean When you specify factory-bean Properties and factory-method as well as @Bean annotation 
if (mbd.getFactoryMethodName() != null) {

return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Candidate constructors for autowiring?
// Find the currently instantiating bean There is @Autowired Annotation constructor 
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {

// If ctors Not empty , It means that there is... On the constructor @Autowired annotation 
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {

return autowireConstructor(beanName, mbd, ctors, null);
}
// Instantiation of parameterless constructor , Most instances are instantiated in the way of parameterless constructor 
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}

A lot of judgment has been made in this method , The first is to get factoryMethodName, When we're in xml To configure bean When it comes to factory-bean Properties and factory-method Property or use @Bean When you annotate, you get the value here , And then it goes through FactoryMethod To create an instance object ; If it doesn't exist factoryMethodName, Then you need to instantiate the object through the constructor , But there may be annotations on the constructor @Autowired, So it needs to pass determineConstructorsFromBeanPostProcessors Get all the tape @Autowired Annotation constructor :

 protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {

/** * adopt AutowiredAnnotationBeanPostProcessor( stay component-scan When parsing * adopt registerComponents Method registered , And then in refresh Call in registerBeanPostProcessors Method * Instantiated ) Class found the tag @Autowired Annotation constructor */
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {

for (BeanPostProcessor bp : getBeanPostProcessors()) {

if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {

SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {

return ctors;
}
}
}
}
return null;
}

Get all the tape @Autowired The annotated constructor is followed by calling autowireConstructor To instantiate , Specifically, it is entrusted to ConstructorResolver Class for processing , Including the above through factoryMethod Creating objects is also delegated to this class . If you don't have @Autowired The constructor of will call instantiateBean Method , Use reflection to create an object and return it through a parameterless constructor , It is also the process of most object instantiation . thus , Instantiation of simple object completed .

addSingletonFactory

This method is to add a three-level cache to solve the problem of circular dependency , Don't analyze .

populateBean

 protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

boolean continueWithPropertyPopulation = true;
// Here, you can write interfaces so that all classes cannot rely on injection , There's no practical use 
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {

for (BeanPostProcessor bp : getBeanPostProcessors()) {

if (bp instanceof InstantiationAwareBeanPostProcessor) {

InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {

// If you need DI, Dependency injection 
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {

return;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {

MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {

autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {

autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
// Focus on this if Code block 
if (hasInstAwareBpps) {

if (pvs == null) {

pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {

if (bp instanceof InstantiationAwareBeanPostProcessor) {

InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// Dependency injection process ,@Autowired Support for 
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {

if (filteredPds == null) {

filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
// The old version used this to complete the dependency injection process ,@Autowired Support for 
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {

return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {

if (filteredPds == null) {

filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
// xml in <property> Dependency injection of tags 
if (pvs != null) {

applyPropertyValues(beanName, mbd, bw, pvs);
}
}

There are three main methods to complete dependency injection :postProcessProperties( At present, it mainly uses )、postProcessPropertyValues( The old version is obsolete API)、applyPropertyValues(xml in property label ). So we mainly look at postProcessProperties Method , And this method comes from InstantiationAwareBeanPostProcessor Interface ( I hope you still remember the inheritance system of this interface ), Mainly look at AutowiredAnnotationBeanPostProcessor, This is to solve @Autowired Dependent injection .

 public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {

InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {

metadata.inject(bean, beanName, pvs);
}
return pvs;
}

See the name and know the meaning ,findAutowiringMetadata The way is to get @Autowired Attributes of the annotation and encapsulated as InjectionMetadata object , Call again inject Do dependency injection , Note that here are properties and methods ( The method is not necessarily setter The method can , As long as it's marked @Autowired And the correct parameter type can depend on success ). This is it. @Autowired The injection process , And then there is @Resource The injection of , stay CommonAnnotationBeanPostProcessor Class , The process is basically the same as this , I won't elaborate here .

initializeBean

The above process is right Bean Instantiation , And the injection of attributes in the object , After all, this Bean Objects are the objects that we can really use directly , So then there is Handle some method calls ( Contains some event notifications ).

 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 {

// call Aware Method 
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {

// Calls to some special methods in the class , such as @PostConstruct,Aware Interface 
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {

//InitializingBean Interface ,afterPropertiesSet,init-method Calling a , It's very important 
invokeInitMethods(beanName, wrappedBean, mbd);
}
if (mbd == null || !mbd.isSynthetic()) {

// The agent may give birth to this instance , yes aop Entrance 
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
private void invokeAwareMethods(final String beanName, final Object bean) {

if (bean instanceof Aware) {

// The interface can be implemented in bean Obtained after instantiation bean The name of 
if (bean instanceof BeanNameAware) {

((BeanNameAware) bean).setBeanName(beanName);
}
// The interface can be implemented in bean Get the current class loader after instantiation 
if (bean instanceof BeanClassLoaderAware) {

ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {

((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
// The interface can be implemented in bean After the instantiation is completed, get the current AbstractAutowireCapableBeanFactory object 
if (bean instanceof BeanFactoryAware) {

((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}

First of all Aware Interface method call , This is very simple. I won't say more . Then there is applyBeanPostProcessorsBeforeInitialization Method call , This is BeanPostProcessor Interface postProcessBeforeInitialization Method call ( See here, will you find yourself misunderstood before , It is thought that this method is called before object instantiation. , In fact, after the instantiation is completed ):

 public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {

Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {

Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {

return result;
}
result = current;
}
return result;
}

Here we focus on the call of several implementation classes :ApplicationContextAwareProcessor(ApplicationEventPublisherAware、ApplicationContextAware etc. Aware Interface call )、InitDestroyAnnotationBeanPostProcessor(@PostConstruct Annotation method call )、ImportAwareBeanPostProcessor(ImportAware Type instance setImportMetadata call , Understanding SpringBoot Help a lot , You can not look here for the time being ).
Close and pass invokeInitMethods Method call InitializingBean Interface afterPropertiesSet Methods and init-method Custom initialization method for property configuration .
In the end, it's through applyBeanPostProcessorsAfterInitialization Method call BeanPostProcessor Of postProcessAfterInitialization Method , Because it involves AOP knowledge , There is no detailed analysis here .
thus ,Bean The analysis of the whole instantiation process is completed , See here , You should be concerned about Bean Have a basic understanding of the life cycle function of , Put the last... On my picture Bean Instantiate the flow sequence diagram :
 Insert picture description here

summary

This article is very long , I have omitted a lot of irrelevant code in the middle , There are also some irrelevant but important codes that have not been analyzed , such as ConfigurationClassPostProcessor analysis @Configuration、@Bean The process of annotation ,FactoryMethod Create object process 、 obtain @Autowired I didn't analyze the constructor of annotation tag and the instantiation process through these constructors , First, it is limited to too much space , Second, it's mainly because it doesn't have much effect on understanding the whole process, and the code is relatively simpler , Interested readers can analyze by themselves after understanding the mainstream process .

copyright:author[Don't talk at night],Please bring the original link to reprint, thank you. https://en.javamana.com/2022/02/202202130726324994.html