Spring learning notes

Posted by dwnz on Wed, 02 Mar 2022 02:49:19 +0100

spring is a framework, a container and an ecosystem!.

spring is singleton by default and supports circular reference. When changing to multiple instances, it is not supported. scope=“prototype”

1.bean life cycle

class - > instantiation - > Object - > attribute filling (dependency injection: @ Autowired attribute assignment) - > initialization - > AOP - > bean - > Destroy


initialization:

① implement interface InitializingBean and rewrite afterpropertieset

② add annotation @ PostConstruct by any method

AOP:

Determine whether the current object needs AOP:

First, go to the spring container and find all faceted bean s to see if the current object has a pointcut execution.

The implementation logic of AOP is to create a proxy object, inherit the original object by the proxy object, then rewrite the method of the original object, and then execute the pointcut logic of AOP.

2. Circular dependency

In singleton mode: first create two objects, and then use the set method to inject attributes

In multi instance mode: when creating A, judge whether there is A dependency. If there is, do not create A first, create B object first, and judge when creating B.. So it can't be created. spring does not solve the problem of circular dependency because the bean object is recreated in the mode of multiple instances and the cache is not used.

The default spring does not solve the circular dependency of constructors, but it can solve the circular dependency problem through @ Lazy annotation and Lazy loading.

spring container create object:

To turn off circular dependencies:

L3 cache:

Why do I need L3 cache?

lambda expressions and functional interfaces are stored in the three-level cache. lambda will be executed only when circular dependency is generated, otherwise it will not be executed.

If there is no AOP or other post processor, there is no need for L3 cache.

1. singletonObjects: cache a bean corresponding to a bean name that has passed through the full life cycle

2. earlySingletonObjects: cache the proxy object obtained after AOP of the original object in advance. The original object has not been subject to attribute injection and subsequent life cycles such as BeanPostProcessor. Avoid repeatedly creating dynamic agents (when there is AOP) when there are multiple circular dependencies

3. singletonFactories: the cache is an ObjectFactory, which is mainly used to generate the proxy objects obtained from the original objects after AOP. During the generation of each bean, a factory will be exposed in advance. This factory may or may not be used. If there is no circular dependency on this bean, this factory will be useless, This bean is executed according to its own life cycle. After execution, it can be directly put into singletonObjects. If there is a circular dependency on this bean, the other bean will execute ObjectFactory to submit a proxy object after AOP (if there is AOP, if there is no need for AOP, it will directly get an original object).

4. In fact, there is also a cache, earlyProxyReferences, which is used to record whether an original object has been AOP.

Principle:

3.IOC Inversion of Control

Control inversion is used to reduce the coupling between codes. The implementation is based on the factory design pattern

It controls the right of object creation. The original object was created by programmer new, and now it is created by spring.

ioc container consists of bean factory, post processor, singleton cache pool, bean definition and other components.

IOC implementation mechanism:
Factory + reflection (beanFactory.getBean() + reflection when creating objects)

refresh() method

Focus of refresh method of AbstractApplicationContext class

// Prepare this context for refreshing.
// Preparation before container refresh: irrelevant
// Set the start-up time of the container. Set the active state to true and the closed state to false,
// Get the Environment object, load it, and prepare the listener and event collection objects
prepareRefresh();

// Tell the subclass to refresh the internal bean factory.
// Create container object (bean factory): DefaultListableBeanFactory
// Load the attributes of the xml configuration file into the current factory, loadbean definitions (beanfactory)
// The most important thing is to wrap the BeanDefinition
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.
// The preparation of beanFactory is to fill in various attributes
prepareBeanFactory(beanFactory);

// ----------------------------
// Allows post-processing of the bean factory in context subclasses.
// Subclass override methods do additional processing. Generally, no extension work is done. It is an empty template method
postProcessBeanFactory(beanFactory);

StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
// Call various beanFactory processors----- BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.
// Register the bean processor. This is just the registration function. The real call is in the getBean method -- BeanPostProcessor
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();

// Initialize message source for this context.
// Initialize the message source for the context, that is, message bodies in different languages, and handle internationalization
initMessageSource();

// Initialize event multicaster for this context.
// Initialize event listening multiplexer
initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.
// Leave it to subclasses to initialize other bean empty template methods
onRefresh();

// Check for listener beans and register them.
// Find the listener bean in all registered beans and register it in the message broadcaster
registerListeners();

// Instantiate all remaining (non-lazy-init) singletons.
// Initialize the instantiation operation of the remaining non lazy loaded singleton object and set the attribute value
finishBeanFactoryInitialization(beanFactory);

// Last step: publish corresponding event.
// Complete the refresh process and notify the lifecycle processor of the refresh process,
// At the same time, issue ContextRefreshEvent to notify others
finishRefresh();

4.DI Dependency Injection

Dependency injection

The difference between IOC and DI: IOC is decoupled and objects are created by IOC container. DI is an implementation of IOC and an important part of the implementation of IOC. Only when an object is injected can an object be created.

5. Notes

@Configuration

This class is equivalent to configuring beans in XML, which is equivalent to the Ioc container. If @ Bean is registered on a method header, it will be used as a Bean in the Spring container, which has the same meaning as the Bean configured in XML@ The class of Configuration annotation must be scanned with < context: component scanbase package = "XXX" /

@ComponentScan

6.BeanFactory function

BeanFactory is a top-level interface. Its main responsibility is to produce beans and realize the design pattern of a simple factory. The most powerful factory is DefaultListableBeanFactory

7.AOP

Principle: dynamic agent. It is used to extract and encapsulate the code of public behavior and logic that has nothing to do with business but has an impact on multiple objects into a reusable module. As section

During AOP, internal calls to other methods of the current class will lead to AOP invalidation. That is, when method B is called inside method A, method B will not be enhanced. Solution: 1 Inject the dynamic proxy objects manually. 2. Expose that the proxy object @ EnableAspectJAutoProxy(exposeProxy = true) exists in the local thread ThreadLocal in the thread. When calling internally, aopcontext currentProxy().

8. Design mode

Topics: Java Back-end