Go deep into IOC and its startup principle

Stack 2020-11-09 10:49:30
deep ioc startup principle


IOC summary

1. IOC summary

Three questions :

  1. IOC What is it?
  2. Why use it
  3. How to use it?

1.1 What is it? ?

Two concepts : Inversion of control , Dependency injection

Take a look at the traditional way of working : On the basis of the principle of single responsibility of the object , It is rare for an object to do its own work without relying on other objects , So there will be dependencies between objects . And it's reflected in our development , It's when you need something , Just create the object , At this point, the control of object creation is in our own hands . When too many objects are created , An object change will appear , You have to change all objects that depend on it , Great coupling . At the same time, there is a serious coupling between objects .

This is the time , We will think , Can we use this object directly when we use it , And leave the ability to create objects to a third party , So we don't have to worry about how objects are created . Give up control of yourself . This is inversion of control

This is the time , There will be another problem , How can we use objects directly . When an object is created , We inject this object into this object , Then you can use it . This is dependency injection

Another question , How is coupling solved ? Through inversion of control, we only use this object , If the object is modified , We just need to modify the way third parties create objects , Is there any object coupling at this time ?

It is IOC Containers , It helps us create objects , And then when the object is used , Inject an object into this object . And because the IOC Creating objects is created by reflection , So it's not as fast as direct new object


I don't understand ??? don 't worry , Listen to the writer tell a story , I like the story most

Some time ago , The weather is getting warmer , Since there is no short sleeve at home , I can only choose to buy . At this time, I have two choices , First of all 、 Go to the clothing manufacturer and buy it directly ( cheap ); second 、 Go to the physical store or online store to buy ( More expensive ). after , Because the author belongs to a member of the army of homestead men , Direct online shopping .

This scenario is a typical process of inversion of control . I don't need to pay attention to how clothes are made , It's just going TaoBao (IOC Containers ) On , Find what you want clothes ( object ), And then just take it and use it . However, due to the existence of middlemen to earn the price difference , therefore The price is more expensive. ( Longer time )

The last two sentences :

Inversion of control : Give your control to a third party you trust , There is no dependence between Party A and Party B

Dependency injection : Open a port for A, And then when it's needed , take B Injection into A in .

1.2 Why

on top , The author has clearly described why to use IOC, The main reason is the coupling between objects .

1.3 How to use it?

1.3.1 XML

By writing XML The configuration file , Add to the container the Bean

1.3.2 Annotation

adopt @Configuration Specify class configuration annotation .

2. IOC framework

One picture , This is IOC The framework of thinking , This is not its execution flowchart .

Let's take a step-by-step interpretation of .

2.1 In vernacular

In the first chapter we learn about IOC To help us Managing and creating objects Of .

At this point, we need a container to hold the information we need to create , That is... In the picture XML Or annotation , So we have our own BeanDefiniton After information , We need an interface to read this information , And there it is BeanDefinitionReader To read our own Bean Information .

So we need to think about a problem , How to produce so many objects ?

The answer is the factory model .Spring The default factory is DefaultListableBeanFactory, you 're right ,Spring All objects in ( Container objects and objects we create ourselves ) It was all created by him . Mass production object

At this time, there is another problem , We don't want to pass BeanFactory Direct production , Some specific treatment needs to be done for this plant , And there it is BeanFactoryPostProcessor, It is used to do some specific treatment for the factory . We can implement this interface ourselves , Customize BeanFactory. Another brother said : I want to create some of my favorite objects alone , arrange ,FactoryBean The birth of , It can help us create an object we need ( The fourth part explains in detail the differences between them ).

That's another brother : I want to have a unified object do something special in my way before it's created , Simple , arrange

BeanPostProcessor There is , He offers two ways : One after object instantiation and before initialization , Execute internal Before Method , After initialization , perform After Method .(Bean Life cycle , The fourth part explains in detail

At this time, some brothers have questions , Not to say that BeanPostProcessor Before the object is created ? How to execute after the creation Before Method .

If you guys know Instruction reordering The concept , Then there must be a case , Creating an object takes three steps

  • Create space ( Instantiation )
  • initialization
  • assignment

Among them, instruction reordering will appear in initialization and assignment

According to this point , It is no problem. get To a point , Instantiation is not the same as initialization .

So there's another point , We are right. Bean Do something , How to operate , It must be modifying the properties , Or add some properties and so on , You need to wait for it to open up space in the heap, that is, execute after the instantiation is completed .

therefore BeanPostProcessor Of before Method is executed after instantiation , Execute... Before initialization .

After a lot of previous operations , Finally, our partner got into our pocket ( In the container ).

About destruction , We usually go through ApplicationContext There is no way to destroy it , It can only be obtained through its subclass implementation , About destroying the same process , First perform an operation before destroying , And then destroy .

2.2 Actual workflow

seen Spring Source code or have heard that there is a method called refresh, He did a lot of things . Of course, his behavior also represents the whole IOC The process of loading and instantiating objects in a container . In Chapter 3, we read the code carefully

Execution process :

  • Load profile , Initialize the system environment Environment Interface
  • Prepare the context , Initialize some configuration resources
  • Create a factory
  • Add a variety of environments to the factory
  • Gets the subclass's own overridden BeanFactoryPostProcessor
  • The execution container and our own BeanFactoryPostProcessor
  • register BeanPostProcessor
  • International processing
  • Repeater
  • Subclass initialization Bean
  • Register listener , Observer mode
  • complete Bean establish
  • Issue corresponding events , Monitor

3. IOC Source code interpretation

Written in the book before :IOC Source code is more complex , So I suggest video learning , As you can B Station search Wutong ( I think it's a good interpretation ), If people don't like the way video is , I want to learn deeply IOC Source code so recommended Jiong Hui, programmer Its blog for IOC The explanation is very in-depth . In addition, the following Spring Source code , The main method is to sort out the process through the diagram , The author's level is limited . If there is any mistake, please leave a message .

3.1 Context configuration start

Creating ClassPathXmlApplicationContext When , These methods are implemented in the constructor .

To put it bluntly , Loaded a loader that parses the path of the configuration file ; Then we get the configuration file through the system environment variable , Do some configuration file de space , Convert expressions and so on ( No parsing was performed ); Finally, it was the one that I marked red ,refresh In the method, it does almost all the work . Let's talk about it

3.2 refresh

This method completes almost all operations , Create a factory , perform Processor wait , Instantiate objects , Turn on event monitoring, etc .

Let's talk about it

3.3.1 prepareRefresh()

The main function of this method is to do some preparatory work for the refresh of application context . Verify resource file , Set the start time and active state, etc .

3.3.2 obtainFreshBeanFactory()

Sure get To , It's mainly about creating a factory BeanFactory, And the configuration file is parsed , To load the Bean Defining information ( It's enough to answer this point directly during the interview , If you want to say, you can put the following bean Information loading chat )

you 're right , What is marked in red is what we will talk about next

This is the process of loading the configuration file , Be careful : There is still no parsing at this time , The resolution is below the marked red

This is the reading process , The specific analysis process comes from parse in , This calls the Java Parsing in XML Class library of , Interested in self browsing , In the end, I returned to a Document object .

adopt Document object , Read the internal label , Execute different methods , Logic and MyBatis The idea of parsing configuration files in is the same , Look through it by yourself .

All the Bean The definition information is saved to BeanDefinitionRegistry Interface , Then we go to subclasses DefaultListableBeanFactory How to register a factory

3.3.3 prepareBeanFactory(beanFactory)

by BeanFactory Prepare some environment , Easy to use when instantiating , Also add the container's own BeanPostProcessor

3.3.4 postProcessBeanFactory

For subclass extension BeanFactoryPostProcessor,

3.3.5 invokeBeanFactoryPostProcessors(beanFactory)

This class , Two interfaces are involved .

  • BeanFactoryPostProcessor
  • BeanDefinitionRegistryPostProcessor Interface , This interface is BeanFactoryPostProcessor Sub interface of , Its priority ratio BeanFactoryPostProcessor Higher

Its overall implementation process is : Execute first BeanDefinitionRegistryPostProcessor Of BeanFactoryPostProcessor, And then execute BeanFactoryPostProcessor

The picture below is BeanDefinitionRegistryPostProcessor Interface processing

BeanFactoryPostProcessor Processing logic

The general logic is to classify first , If you've dealt with it, skip it , They haven't been dealt with , Sort it out , The logic is the same as above .

3.3.6 registerBeanPostProcessors

The logic of this method is the same as above , It's just that the above is directly executed BeanFactoryPostProcessor, And this is just registration, not execution .

First of all, get all the... In the factory BeanPostProcessor Type of Bean, And then sort it out , Sort registration .

3.3.7 initMessageSource()

Implementing international content

3.3.8 initApplicationEventMulticaster

A multicast was created , To add Listener Provide support .

The main logic :

  • Is there... In the container applicationEventMulticaster, If direct registration exists
  • If it doesn't exist , Create a SimpleApplicationEventMulticaster, Register in container .
3.3.9 onRefresh()

Subclass extension

3.3.10 registerListeners()

The realization of observer pattern

protected void registerListeners() {
// Get the listener in the current container , Register to multicast
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Get the monitor in the container Bean, register
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Clear started events , To the broadcaster
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
3.3.11 finishBeanFactoryInitialization

There is too much in this part , So use code and diagram to explain .

 /**
* Finish the initialization of this context's bean factory,
* initializing all remaining singleton beans.
Complete all in the context factory Bean The initialization
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initializing context conversion service Bean
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// If there is no antecedent parser , Then register a default embedded value parser , It's mainly about annotation attribute parsing
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// initialization LoadTimeWeaverAware
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// Instantiation , a key
beanFactory.preInstantiateSingletons();
}

The following is the creation of Bean Main process of

Say one by one according to the serial number on the way :

  1. BeanDefinition Do you need to merge .BeanDefinition According to different types of profile information , Will Bean Package to different Bean In the information definition class . For example, we often use the configuration file version of GenericBeanDefinition; Scanned version of annotation ScannedGenericBeanDefinition wait .

And in the process , Parent and child definitions , We need to merge when we actually process the definition information , There are three main aspects

  • There is parent definition information , Use the parent definition information to create a RootBeanDefinition, Then pass in the custom information as a parameter .
  • There is no parent definition information , And the current BeanDefinition yes RootBeanDefintion Type of , Return one directly RootBeanDefintion The clone
  • There is no parent definition information , And the current BeanDefintion No RootBeanDefintiton Type of , Directly through the BeanDefintion Construct a RootBeanDefintion return

The above process is also the execution process in the source code

  1. isFactoryBean. Judge whether it is FactoryBean

A brief introduction :FactoryBean Let developers create their own needs Bean Interface . Internally, there are three ways

T getObject() throws Exception;// Back to Bean Information
Class<?> getObjectType();// Back to Bean type
default boolean isSingleton() {return true;}// Is it a single case

When we go through GetBean Directly Bean When , What you get is the return specified by the factory Bean type . If you want to get the Bean In itself , You need to get... Through a prefix &

@Override
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name); // Analysis of real BeanName
Object beanInstance = getSingleton(beanName, false);// Get... In the container bean
if (beanInstance != null) {// If there is... In the container , Go straight back to the Bean Is it FactoryBea type
return (beanInstance instanceof FactoryBean);
}
// No, Bean Information , Check this Bean Information
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
// Get from parent factory
return
((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
}
//MergedBeanDefinition To check beanName Corresponding Bean Is it FactoryBean
return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}

Another point , This is to take from the container Bean Main methods , It's also the logic of solving circular dependency

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Check whether the current container has the Bean
Object singletonObject = this.singletonObjects.get(beanName);
// If it doesn't exist , And the current Bean Being created
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// From early containers Bean
singletonObject = this.earlySingletonObjects.get(beanName);
// If the early container does not have and allows the creation of an early reference
if (singletonObject == null && allowEarlyReference) {
// Get the Bean Of ObjectFactory factory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
// If the current factory is not empty
if (singletonFactory != null) {
// Create an object instance , At this point, it is in the semi initialization state
singletonObject = singletonFactory.getObject();
// Add to previous references
this.earlySingletonObjects.put(beanName, singletonObject);
// Remove the factory that created the early reference , Because it's time to Bean Has been created and added to the early container , No need to create it again .
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}

Let's talk about how it solves circular references ?

It introduces the concept of a three-level cache

/** All the singletons are stored Bean */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Deposited Bean Create what you need ObejctFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** Stored in the Bean, At this time Bean No property assignment was made , Just create an instance through the constructor */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
// Creating Bean
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));

When a circular reference occurs , It first passes ObejctFactory The factory will Bean created , In this case, the object has no property assignment , Just opening up space in the heap . And then I'm going to take this Bean Add to earlySingletonObjects In the container , That is to say, the container contains Bean It's all semi-finished products . And in the subsequent attribute assignment , Because the object is a singleton , So the reference address doesn't change , That is, the object is ultimately complete .

  1. getBean. All objects are created directly by this method , This is also Spring The core method

Let's take a look at the whole process

Its main logic is : You need to get the current instantiation first Bean The real name of , Mainly to deal with FactoryBean, When I get it , From the current container, see if the Bean, If there is a direct return .

If it doesn't exist , Obtain its parent factory , If the parent factory is not empty , And there is no current in the current container Bean Information about , Try to get from the parent factory Bean Defining information , Conduct Bean Instantiation

If the parent factory is empty , Will the current Bean Information stored in alreadyCreated In cache .

Get current Bean Merge information for (getMergedLocalBeanDefinition), View the current Bean Is there a dependency , If there is, judge the current Bean And dependence Bean Is it a circular dependency , If it is not a circular dependency, create the dependency first Bean

Judge the present Bean Scope of action .

If at present Bean It's a singleton object , Create directly Bean example

If at present Bean Is a multi instance object , Will the current Bean Information is added to the cache being created , Remove after creation

If at present Bean It's other types , Such as Requtst,Session Other types , Then customize one ObejctFacotry factory , rewrite getObject Method , Create objects

After object creation , Judge whether the current object is the one you need , If it's straight back ; If it's not for type conversion , If the type conversion fails , Direct throw anomaly

Let's take a look CreateBean Implementation

The main task of this method is : adopt Bean Get the corresponding name Class object ; If at present Bean Acquired Class Object is not empty and the RootDefintiton This can be obtained directly Bean, Clone a copy of Bean Defining information , Convenient for later use .

Verify current Bean Upper @Override Information . perform BeanPostProcessor, Returns a proxy object ( If there is an agent )

If there is no agent , Then create Bean

Now let's talk about this thing ——resolveBeforeInstantiation

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
// The current definition information is not a merge , And there are Bean Intensifier
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// obtain Bean Of Class type
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// If not for null, The preprocessor is executed
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// If the front processor is not null, Then the post processor executes , skip spring Default initialization
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
// Represents that it has been parsed before re instantiation
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}

Come on , continue , Take a look at the preprocessor logic

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// Get all the things in the factory BeanPostProcessor
if (bp instanceof InstantiationAwareBeanPostProcessor) {
// Find all the enhancers we need
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// Returns a proxy instance
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}

The post processor doesn't look at it , All the post processors are called , And then it did it again , There is no other logic .

Let's move on to our main topic :doCreateBean

The general process is shown in the figure above :

First judge whether it is a single case later , And then from FactoryBean Check the cache to see if there is any Bean, If there is, take it out , If it doesn't exist, create a current Bean Wrapper class instance of . Then get the instance and instance type of this class , Post processor after execution .

At present Bean Is it a single case , Is circular dependency allowed , It's time to create , If it is , Create a current Bean Of ObejctFactory To solve the problem of circular dependency

fill Bean Properties of , Conduct Bean Instantiation .

View previous container cache ( Whether there should be in the secondary cache in the cache Bean). If there is , It shows that there is cyclic dependence , Then deal with it

Look at the circular dependency first

if (earlySingletonExposure) {
// From the early Bean Get the instance object in the container , At this time Bean There must be circular dependence
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// Get all of the dependencies Bean Information
String[] dependentBeans = getDependentBeans(beanName);
Set < String > actualDependentBeans = new LinkedHashSet < > (dependentBeans.length);
for (String dependentBean: dependentBeans) {
// Get rid of these Bean Information , At this time Bean It's dirty data
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
// Unable to clean deposit actualDependentBeans in
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}

Come on ,createBeanInstance

Spring Provides three ways to create object wrappers :

  • Create directly through the provider object object .obtainFromSupplier
  • Create directly through the factory method .
  • Created by default .
    • Whether the constructor needs automatic injection
    • The constructor does not need to be injected automatically , Call the default constructor

After this method is executed , One thing you should know is : At this point, the object instance has been created , All that's left is to execute a series of enhancers and initialization methods , Attribute padding and so on .


Let's do it in the order in which the code is executed , Attribute filling is populateBean

This method executes the logic :

First, judge the incoming Bean Is it null, If null Then judge Bean Define whether the attribute value exists in the information , If there is , abnormal ; If there is no skip

At present Bean Define whether the information is merged , If it is and there is InstantiationAwareBeanPostProcessors, Then modify it before the property is filled in Bean Information about

Get all the attribute values , Automatic injection method for parsing attribute values ,Type perhaps Name, Automatic injection

Judge whether it exists InstantiationAwareBeanPostProcessors, Modify the previously set properties

Determine if there is a dependency check , Checking depends on

Attribute assignment


Next, let's look at executing the initialization method , It's called BeanPostprocessor,init Other methods

This is the execution flow chart of this method , Believe in this place , People should be concerned about why BeanPostProcessor Of before Methods in init Method implementation . The purpose of this method is only to print a life cycle , Object has been created before .


Let's take a look at the method of destruction .registerDisposableBeanIfNecessary

For a single case Bean Come on ,Spring Will need to be destroyed Bean It's in storage disposableBeans In cache , adopt DisposableBeanAdapter Encapsulated destruction Bean

For other scopes , Custom destroy callback function , But in the end, it was packaged as DisposableBeanAdapter

In the package as DisposableBeanAdapter In the process of , Will first judge the Bean Whether there is destroy Method , Then assign a value to destroyMethodName Variable . Again, determine the parameters of this method , If the number of parameters is greater than 1, Throw an exception

3.3.12 finishRefresh

This method does a series of resource cleaning and

protected void finishRefresh() {
// Empty context resource cache
clearResourceCaches();
// Initialize life cycle processor
initLifecycleProcessor();
// Propagate the refreshed processor ( Throw it ) In the lifecycle processor
getLifecycleProcessor().onRefresh();
// Push context refresh time to the corresponding listener
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}

initLifecycleProcessor, This method is extremely simple , Just look at the current situation Bean Whether there is a lifecycle processor in , If there is, use this directly , If it doesn't exist, create a default , And register as a singleton and throw it into the container .

4. Common topics

4.1 Bean Life cycle of ?

Spring The official explanation is BeanDefinition Interface comments

answer :Bean The complete life cycle is :

  • Set up a series of Aware Function of interface
  • Instantiation Bean
  • call BeanPostProcessor Of before Method
  • perform InitializingBean Interface method afterPropertiesSet
  • perform init Method
  • call BeanPostProcessor Of postProcessAfterInitialization Method
  • call DestructionAwareBeanPostProcessors Interface postProcessBeforeDestruction Method
  • call destory Method

4.2 FactoryBean and BeanFactory The difference between

answer :BeanFactory yes Spring Factory of default production object .

FactoryBean yes Spring Provides a factory that produces specific types and specific objects . for example Mybatis-spring Medium SqlSessionFactoryBean It was created in this way .

4.3 What is circular dependence ?Spring How to deal with circular dependencies ?

answer : Circular dependency is defined as : Creating A Objects need to be injected B object ; Creating B Objects need to be injected A object , The two are interdependent .

There are two cases of circular dependency :

  • The constructor depends on ( Unable to resolve )
  • Attribute injection ( Can solve

Resolve circular dependency ,Spring The concept of three-level cache is introduced . The source code explanation above has introduced

  • singletonObjects All the singletons are stored Bean, All the Bean The information is complete
  • earlySingletonObjects Stored in the early Bean, At this point, only one is created Bean example , No attribute population
  • singletonFactories Deposited Bean Our factory

Spring By creating Bean The factory is exposed , Then, in the case of circular dependency, a common one through this factory is bean, And then put this Bean Inject , Because the object is singleton , So in the next attribute filling , Can be guaranteed for the same object , thus , Circular dependency release .

Use Three Prince Ao Bing A word of : The process of solving the cyclic dependence is the process of the sum of two numbers in the first question of the force buckle

4.4 What is? IOC

answer :IOC There are two points :

  • Inversion of control . Give control of common objects to a third party , The third party here is Spring
  • Dependency injection . Objects that need to be used in a class , It's all injected from a third-party container through reflection rather than creating it yourself . The third-party container here is Spring

4.5 ApplicationContext and BeanFactory The difference between

answer :

  • ApplicationContext Load now is used , The object is created when the configuration file is loaded .BeanFactory The method of delayed loading is adopted , Created only when used .
  • about BeanPostProcessor and BeanFactoryProcessor for ,BeanFactory It's manual registration ,ApplicationContext Automatic registration is adopted .

4.6 Spring What design patterns are used in the framework ?

answer :

  • The singleton pattern . It doesn't need to be said much
  • The proxy pattern .AOP Used
  • Decorated with patterns .BeanWrapper
  • Factory mode .BeanFactory, When creating objects
  • Template method pattern .JDBCTemplate
  • Observer mode . Various event monitoring
  • ……

More original articles and Java Series of lectures on official account @MakerStack

版权声明
本文为[Stack]所创,转载请带上原文链接,感谢

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云