IOC summary
1. IOC summary
Three questions :
IOC What is it?
- Why use it
- 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 isBeanFactoryPostProcessor
Sub interface of , Its priority ratioBeanFactoryPostProcessor
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 :
BeanDefinition
Do you need to merge .BeanDefinition
According to different types of profile information , WillBean
Package to differentBean
In the information definition class . For example, we often use the configuration file version ofGenericBeanDefinition
; Scanned version of annotationScannedGenericBeanDefinition
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
yesRootBeanDefintion
Type of , Return one directlyRootBeanDefintion
The clone - There is no parent definition information , And the current
BeanDefintion
NoRootBeanDefintiton
Type of , Directly through theBeanDefintion
Construct aRootBeanDefintion
return
The above process is also the execution process in the source code
isFactoryBean
. Judge whether it isFactoryBean
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 .
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
Ofbefore
Method - perform
InitializingBean
Interface methodafterPropertiesSet
- perform
init
Method - call
BeanPostProcessor
OfpostProcessAfterInitialization
Method - call
DestructionAwareBeanPostProcessors
InterfacepostProcessBeforeDestruction
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 storedBean
, All theBean
The information is completeearlySingletonObjects
Stored in the earlyBean
, At this point, only one is createdBean
example , No attribute populationsingletonFactories
DepositedBean
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
andBeanFactoryProcessor
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 Official account of series @MakerStack