A brief discussion on spring core

       

We all know that the two cores of spring are: IoC (Inversion of Control) and AOP (Aspect-Oriented Programming); and in the current era of microservices, the relationship between springCloud, springBoot, and spring; this article mainly wants to elaborate on the relationship between these two Please correct me if there are any mistakes in your understanding of the problem;

1. The relationship between SpringCloud, SpringBoot and Spring

The relationship between Spring and SpringBoot.
To put it simply, SpringBoot is based on the Spring framework and is an upgraded version of Spring. The advantages of SpringBoot compared to Spring are: it simplifies Maven dependencies; the configuration that originally requires xml can be configured with annotations; by re-encapsulation and Shielding out complex configuration and implementation principles, it finally provides developers with a set of distributed system development toolkits that are easy to understand, deploy, and maintain.
Spring Boot was invented not to replace Spring, but to make it easier for people to use Spring.

The relationship between SpringBoot and SpringCloud
Spring Cloud is an ordered collection of a series of frameworks. It uses the development convenience of Spring Boot to cleverly simplify the development of distributed system infrastructure. Service discovery registration, configuration center, message bus, load balancing, circuit breaker, data monitoring, etc. can all be started and deployed with one click using the Spring Boot development style. Spring Cloud is a service governance solution under a microservice architecture developed based on Spring Boot.

In general, SpringCloud is based on SpringBoot, and SpringBoot is based on Spring.

2. The two cores of Spring are: IoC (Inversion of Control) and AOP (Aspect-Oriented Programming);

Putting aside the two cores of Spring, when we first learn Java, we naturally have to write code like this:

We encapsulate some logic into ServiceB. When ServiceA needs to use these logic, a new ServiceB is created inside ServiceA.
If the logic encapsulated by ServiceB is very general, there will be ServiceC...ServiceF, etc. that all need to rely on it. That is to say, new ServiceB will be needed everywhere in the code. In this way, if its construction method changes, you will have to use it in all places. Go to its place and make code modifications.

For example, the creation of ServiceB instance requires ServiceC, so the code is changed to this:

There is indeed this problem.

But in fact, if we encapsulate common service logic, there is no need to create new instances every time. In other words, a single instance is enough. Our system only needs a new ServiceB for each object to use, which can solve this problem.

It looks like the problem has been solved, but it is not.
When the project is relatively small, such as a large university assignment, the above operation is actually not a big problem, but it becomes complicated when it comes to enterprise-level applications.
Because there is a lot of logic involved, there are many encapsulated service classes, and the dependencies between them are also complex. There may be ServiceB1, ServiceB2...ServiceB100 in the code, and there may be dependencies between each other.

Regardless of dependencies, let's take the simple singleton logic code of ServiceB. The repeated logic may need to be written in hundreds or thousands of copies.

And it is not easy to expand. In the past, the operation of ServiceB may not require transactions, but later it will require transactions. Therefore, it is necessary to change the code of ServiceB and embed transaction-related logic.

Not long after, ServiceC also required transactions, and the exact same code about transactions had to be repeated on ServiceC, as well as D, E, F...

The requirements for several Service transactions are different, and there is also the problem of nested transactions. In short, it is a bit troublesome.

I have been busy for a while to meet transaction requirements and went online. I thought I was finally free from the nightmare of repeated code and could take a good rest.

Then came another requirement. Because we often need to troubleshoot online problems, we need to log the interface input parameters to facilitate troubleshooting, and we have to make drastic changes all at once.

It is normal to make changes when necessary, but each change requires a lot of repetitive work, which is tiring, has no technical content, and is easy to miss. This is not elegant enough.

 1.IOC (Inversion of Control);

So, we want to implement it like this. We only care about ServiceA depending on ServiceB, but we don't care how ServiceB is generated. That "thing" helps us generate it and associate ServiceA and ServiceB.

This "thing" is the object code managed by Spring and those XML files (or classes marked with @Configuration).
The current logic is, which ServiceB does ServiceA specifically depend on? We don't need to explicitly write the complete logic on how to create ServiceB in the code. We only need to write the configuration file, and Spring will help us with the specific creation and association.

Let’s take an example of database configuration in Spring:

You can see that our drawings are written very clearly. The MapperScannerConfigurer that creates mybatis needs to tell it the values ​​​​of two properties. For example, the first one is sqlSessionFactoryBeanName, and the value is sqlSessionFactory.

The sqlSessionFactory relies on dataSource, and dataSource needs to be configured with driverClassName, url, etc.

Therefore, in fact, we know very well what is needed to create a ServiceA (Bean), but the creation process is handled by Spring, and we only need to tell it clearly.

Therefore, it does not mean that after using Spring, we no longer care about which ServiceB ServiceA depends on and how ServiceB is successfully created. It means that Spring helps us with the process of assembling these objects.

We still need to know clearly how the object is created, because we need to draw the correct drawing to tell Spring.

So Spring is actually a machine that automatically creates associated objects for us to use based on the drawings we give it. We don't need to explicitly write the complete creation code in the code.

These object instances created by Spring are called Beans.

If we want to use these beans, we can get them from Spring. Spring puts these created singleton beans in a Map, and we can get these beans by name or type.

This is IOC.
ps: SpringBoot lacks a lot of this kind of xml configuration, and basically uses annotations or other methods; so the xml configuration method of beans in spring is more helpful for beginners to understand IOC.

ps: SpringBoot lacks a lot of this kind of xml configuration, and basically uses annotations or other methods; therefore, the xml configuration method of beans in spring is more helpful for beginners to understand IOC;

 2.AOP (aspect-oriented programming);

 Precisely because these beans need to be created by the Spring machine, instead of lazily creating them in every corner of the code, we can easily do many things based on this unified interface.

For example, when our ServiceB is marked with the @Transactional annotation, Spring can parse this annotation and understand that ServiceB requires a transaction, so the opening, submission, rollback and other operations of the transaction are woven into it.

Everything marked with the @Transactional annotation will automatically add transaction logic, which reduces too much repetitive code for us. As long as we add the @Transactional annotation to the method or class that requires transactions, Spring will help us supplement the transaction function. Repeat All operations are completed by Spring.

For another example, we need to record the request input parameters on all controllers. This is also very simple. We only need to write a configuration to tell Spring that the input parameters of each method of the class under the xxx path (controller package path) need to be recorded in the log. , and also write the log printing logic code.

Spring got this command after parsing this configuration, so when creating the subsequent Bean, we will see if the package it is in conforms to the above configuration. If it does, we will add log printing logic and weave it together with the original logic. .

In this way, the repeated log printing action operations are abstracted into a configuration. After the Spring machine recognizes the configuration, it executes our commands to complete these repeated actions.

We have a certain understanding of the origin and core concepts of Spring, and there are many things we can do based on the above features. With the unified closing processing of Spring, we can flexibly provide many extension points at different times, such as when parsing configuration files, before and after Bean initialization, before and after Bean instantiation, etc. Therefore, we need to use Spring Family Bucket. The extensions and encapsulation it provides can flexibly meet our many needs, and these flexibilities are based on Spring's core IOC and AOP.

ps: Those who are interested can learn about Spring Family Bucket;

Let’s briefly describe the principle of Spring:
Spring parses the content according to the configuration class and XML configuration file we provide, and obtains the information of the beans it needs to manage and the relationships between them, and Spring exposes many extension points for us to customize. Such as BeanFactoryPostProcessor, BeanPostProcessor, we only need to implement this interface to perform some customized operations.

After Spring obtains the Bean information, it will create a Bean instance based on reflection and assemble the dependencies between the Beans. It will intersperse the native or relevant PostProcessor defined by us to transform the Bean, replace some attributes or proxy the original Bean logic.

Finally, after all the beans with configuration requirements are created, the singleton beans are stored in the map, and the BeanFactory is provided for us to obtain and use the beans.

This allows us to no longer need to pay attention to how the Bean is created during the coding process, and also saves a lot of repetitive coding actions. These are all done for us by the machine we created - Spring.

 

 

Guess you like

Origin blog.csdn.net/weixin_43500974/article/details/131089459