Tear the core source code of spring by hand, and thoroughly understand the spring process

Introduction

More than ten years ago, programmers who had just worked for a while could still live a very easy life. I remember that there were some development and testing girls in the company at that time, who often had problems that could not be solved. No matter what field problems came to me, I could help them solve them. But at that time, I didn’t have the awareness of actively learning technology, I was just content to solve problems, and I missed the best stage of ability improvement.

My husband is the opposite type, I just see him studying in the dormitory every day. Learning to learn is the same. He didn't play with me. Although I wasn't happy in my heart, it was fortunate that at that time, I didn't know what to expect: I knew that I could have a handsome son, who had similar interests to me, clinging to me every day, and he could laugh out loud when I was next to him when he slept. I put up with it. I just studied history and literature by myself, went out to a foreign language training class, and learned whatever I was interested in. It's just that you don't learn what you're doing at work.

Only later did I realize that I had made a big mistake: not establishing a systematic knowledge system and thinking as soon as possible, which also affected the continuity and logic of thinking. In martial arts stories, it is deceptive to get magical power overnight, and kung fu is still normal. The husband seems to have done little things for more than ten years, but the foundation is very solid and skillful. But if he can be more active in his mind and master the essentials, he can achieve twice the result with half the effort.

Many friends want to learn Spring, and they always go from getting started to giving up quickly. The reason is that there is no framework in the mind, and what is learned is not indexed, and ends up being buried deep in memory. By tearing the core source code of spring by hand, this article aims to allow everyone to form a spring framework in their minds, and then they can look at the source code with problems at work, add branches and leaves to this framework, and finally form a full spring knowledge system .

The whole paper adopts a logical structure from shallow to deep. Focus on friends who have written business code with spring in their usual work or study.

HelloWorld version Spring boot code

Some friends may have written or seen ClassPathXmlApplicationContext and AnnotationConfigApplicationContext, which are all common spring containers or contexts. Now that we are here, let's first explain what is a spring container and what is a spring context.

The core of Spring is the container, which is responsible for the entire life cycle of objects: creating, managing, and destroying objects needed during program execution.

Spring containers are divided into two types: the first is BeanFactory, the simplest container, which can only provide basic DI functions) The other is: ApplicationContext derived from BeanFactory, which is called Spring context. Can provide more enterprise-level services. The most commonly used is the context container based on IOC (Inversion of Control) .

Now SpringBoot uses a lot, so today we mainly tear up the principle of implementing the annotation context of AnnotationConfigApplicationContext.

Let's start tearing. Referring to the method we use spring below, we must first have a context to pass in the configuration parameters, and then have a getBean to get the object to use.

c8007228333eb0c13b6175e23751890b.png

Then let's write a class based on these two characteristics. The main points are as follows in Figures 1 and 2.

51c9e04abe0e5e62de4563071dc68e49.png

Since the configClass configuration class needs to be passed in as a parameter, let's construct an empty configuration class first.

bccc8beab7ad8e7e619fb5fd08317397.png

In this way, on the surface, you can use the Spring container like AnnotationConfigApplicationContext.

09c38f8e60abcdc7c45c14c0a8ab9ff8.png

In order to mark the key points and shield the differences in article reading experience caused by differences in user terminals, here I directly use screenshots. The code text can be found at https://github.com/xiexiaojing/yuna.

Tear Spring Scanning Process

The so-called HelloWorld version means nothing but entry. We hope that it can automatically scan the beans annotated with @Component under the folder to complete the injection. First, create a new @Component annotation yourself:

1c348d80b2ffba313e05b0ca68f0991e.png

and use this annotation in UserService:

515a27e7713f21114427a36d716172fe.png

Of course, the Component annotation is used for scanning, so you have to define a scanning annotation, that is, copy the Component annotation and change the name:

d5a9fb839bc51c2314474835173f672b.png

The ComponentScan annotation should be added to YunaConfig to load the scan configuration:

c0df31c7b16262675f54e6d2bcb4d577.png

Let's go back to YunaApplicationContext. After the configuration class is defined, let's parse it in the next context:

06ca02d23083d4ccb1e99e8a871c9d14.png

At this time, let's go back to the main method and run the result:

8d895ff61a6ea5bc26b8ae167d727b8c.png

We got the resolution path, but the UserService bean is still empty. Here comes the point, pay attention to the following code:

4066b481d79e30e60d5a96690654b194.png

The above first uses the hutool tool to scan the path to obtain a collection of classes under the package, and then filter the classes that use the Component annotation from the collection. Is it quite simple?

Of course, the class here has not been instantiated, so just print the class name to see the effect:

8b9fe460e330a76012e6b144fbb2c01c.png

From the results, you can see that the class has been obtained. The next step is to instantiate.

Tear Spring instantiation object process

There are two main scopes for instantiating objects. One is singleton and one is multiple. Again, it's up to the user to choose. The choice for the user is through annotations. Then make a copy of the Component annotation class and rename it to Scope. value defaults to singleon, a singleton.

6b58861505356f84cd8901bbe3fd5fc2.png

An instantiated object needs a container to store. First, an object BeanDefination must be defined to store the description of the object:

35d7a2bed13af8adf87122fe81b4b4a7.png

Each class corresponds to a BeanDefination, which is stored in a map container:

0b167ae0a6ffe5bc6a5f30f4ec763fe9.png

When you want to get an instance, you need to judge whether it is a singleton. For a singleton, use a map to store it and use it directly next time you get it. If it is not a singleton, it is directly instantiated.

fd8b22a3d4024ea643662cf25d4aae5a.png

Run to see the effect:

0ea226aeefc868e19d37d43368733579.png

This time it's not null, but a concrete instance. But we are not satisfied with getting it with getBean, let's see how to inject automatically.

Tear Spring Dependency Injection Process by Hand

First, define the annotation Autowired for ige logo injection:

fdfffe2b066e22e940a7f81b728ed46d.png

Then arbitrarily define a Bean for injection testing:

03ef9e192c5e4970296aa993a9aa410e.png

Injected into the UserService object:

87a0d6024e5753849605ba83b69c6f0f.png

Extract a method separately from the place where newInstance is instantiated. When instantiating, get whether the class has Autowired annotation, and some instantiate it first:

d0f4e6c64f8bdee7d01b320c3b618197.png

Test effect:

a0b0cea75d2419d4c2141e8f016d36b9.png

Summarize

The code here is commonly used in business development, and I don't explain it much. Do you feel that the whole process is as smooth as doing business development? In fact, writing the underlying container is like this. It is not difficult to understand the principle.

After you finish this article, it is recommended to read other spring articles, and try to have a deep understanding?


Classic error used by Spring Boot - Bean not found

Asynchronous BUG of Spring Kafka


Java & Spring outdated classic quotations

programming for a lifetime

Because the official account platform has changed the push rules, if you don't want to miss the content, remember to click "Watching" after reading it, and add a "star", so that every new article push will appear in your subscription list for the first time.

PDCA methodology , check if you miss the update: I will update the article every Wednesday around 8:00 pm, if you don't receive it, remember to open the [Programming Life] public account to find it (*^▽^*). If not found, it may be like this week, I remember the wrong day (꒦_꒦)

Guess you like

Origin blog.csdn.net/xiexiaojing/article/details/123766814