Spring source code overview


                                                                              

Spring is roughly divided into IOC and AOP, as shown in the following figure:

 

 

 

 

 

IoC: Use containers to control the dependencies between business objects. Control is transferred from the application code to the external container, and the transfer of control is the reversal. The meaning of control transfer is to reduce the degree of coupling between classes.

 

When creating an object, set values ​​to the properties in the class. There are mainly two ways of spring dependency injection:

(1) Use the set method (commonly used)

(2) Use the constructor with parameters

 

 

A simple understanding of spring's IOC is roughly the following process:

 

In fact, the core is the IOC container, which is used to store Bean or BeanDefintion information. We usually think of Map, which is used for storage. Common containers store K'and V values, as follows:

 

The ObjectFacotry here is mainly used to solve the circular dependency, and we will talk about this in detail later.

 

Continuing to talk about the definition information of Bean, the common ones are xml, annotations, properties, yaml, etc. We need to uniformly read various format files that define bean information and parse them into BeanDefintion information, then we need a unified interface, BeanDefinitionReader., As shown below

 

View the source code, implemented subclasses:

 

In addition to implementing the BeanDefinitionReader interface, spring also has some other BeanDefinitionReaders. Although they do not implement BeanDefinitionReader, their functions are roughly the same, but the principles are different. Such as: AnnotatedBeanDefinitionReader, ConfigurationClassBeanDefinitionReader, JdbcBeanDefinitionReader, not specific here, and will be discussed separately later.

Speaking of this, it is necessary to say, BeanFactory,

Bean factory, the root interface of the entire container, is also the entrance of the entire container.

Instantiate objects through reflection as follows:

Constructor ctor= clazz.getConstructior();

Object obj =ctor.newInstance();

 

 

It is also necessary to mention: bean scope, scope, commonly used singleton, prototype.

 

Singleton is the default scope. When defining a Bean, if the scope configuration item is not specified, the scope of the Bean is defaulted to singleton. Singleton belongs to the singleton mode, in the context of the entire system, there is only one Bean instance. In other words, in the entire system context, all you get through Spring IOC are the same instance.

 

When the scope of a Bean is defined as prototype, it means that the Bean that the program gets from the IOC container is a new instance each time. Therefore, prototype scope should be used for stateful beans, and singleton scope should be used for stateless beans.

 

When the Spring IOC container creates a Bean instance, you can specify the scope of the instance for the Bean. The scope includes singleton (singleton mode), prototype (prototype mode), request (HTTP request), session (session), global-session (global-session) Conversation).

 

 

Creating an object can be divided into two parts, instantiation and initialization.

 

Instantiate, open up a memory space in the heap, and assign default values ​​to the attribute values ​​of the object, such as basic attributes. Int is assigned a value of 0, and the object attribute is assigned a value of null.

 

Initialization, assign values ​​to attributes, fill in attribute values, execute initialization method, init-method.

 

 

 

What should I do if the definition information of the bean needs to be changed during the container creation process?

For example: we sometimes configure the connection information of the database, as shown below:

 

Here is a point of knowledge, the operator behind the scenes is the PostProcessor in Spring

 

 

 

There are two types of post processors: BeanFactoryPostProcessor and BeanPostProcessor

 

There is only one postProcessBeanFactory method in the BeanFactoryPostProcessor interface. Combining the interface annotations and the method annotations in the interface, it can be concluded that this interface is a BeanFactory hook interface. To implement this interface, you can use the postProcessBeanFactory method to call after the BeanFactory is instantiated and before the Bean is instantiated. This interface modifies the BeanDefinition or BeanDefinition metadata in the BeanFactory.

 

BeanDefinitionRegistryPostProcessor

 

BeanDefinitionRegistryPostProcessor inherits BeanFactoryPostProcessor. Before Bean is instantiated and detected, it implements a very important function, dynamically registering a BeanDefinition. In addition, you can also modify the registered BeanDefinition information.

 

BeanPostProcessor

 

BeanPostProcessor is a Bean post processor interface, which contains two methods: postProcessBeforeInitialization and postProcessAfterInitialization. The former is called before the bean is instantiated, and the latter is after instantiation. For example, generating a proxy class for a Bean is done by its subclasses.

 

Don't underestimate the above three interfaces. Most of the important Spring technologies are implemented by subclasses of these three interfaces. They are also extended interfaces. You can customize the classes to implement them to enhance or extend Spring functions. Or a third-party framework.

 

Let's talk about this in detail later.

 

So the general process is: locate the configuration file, load the bean information, read and parse the bean information, and convert it to: BeanDefinition. In the middle process, you can modify or enhance the BeanDefinition, instantiate objects, fill in attributes, and set the Aware interface. Attributes are enhanced before bean initialization, execute init-method, and then enhance after bean initialization, and finally generate a complete object, store it in the container, and get it from the container when needed.

 

Here is a special note: Aware interface,

Aware.java is an interface that does not define any methods. It has many sub-interfaces. Many places in the spring source code are using these sub-interfaces to complete callback operations in various scenarios. When business needs, we only need to create classes to Implement the relevant interface, and then declare it as a bean, it can be actively called back by the spring container;

 

Here is a simple example:

 

For example: we want to get the ApplicationContext object in a class, how to get it, define a class, and implement the ApplicationContextAware interface

 

Implement the setApplicationContext method, define a private ApplicationContext object, assign a value in the setApplicationContext method, and then define a getApplicationContext method for external use.

 

 

If you need to get other properties or objects in the container, you can get them by implementing the Aware interface and let the container callback assignment.

 

Where exactly is the method we defined in the container called? Look at the source code: the doCreateBean method in the AbstractAutowireCapableBeanFactory class.

 

 

 

 

 

Here is another abstract class AbstractAutoProxyCreator, which is mainly used to implement AOP and create dynamic proxy objects.

 

 

 

 

 

 

 

 

 

 

Finally found that there are two dynamic agents cglib and jdk.

 

If you look at the source code and need translation, you can install the plug-in: as shown below:

 

 

 

Let's continue to talk about the life cycle of the bean, you can first look at the source code: BeanFactory

 

Here is another question: What if: different tasks are to be handled at different stages? Spring is implemented through the observer mode: listener, event monitoring, and multicast (broadcaster). In the Refresh method of AbstractApplicationContext, as shown below:

 

 

If you look at the source code, you can pay attention to some key interfaces, as follows:

 

Here you can see when the Environment was created,

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Finally, let’s talk about the difference between BeanFacotry and FactoryBean. This is also the favorite to ask in interviews.

 

Customize a class first

 

 

 

 

 

 

If you need to get the factory bean, you need to add the ampersand

 

So where is the getObject() method called?

Let's take a look at the source code: start from the getBean method

 

Find doGetBean, some steps are omitted in the middle

 

 

 

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/huzhiliayanghao/article/details/115014979