Click the link below to check out the original article:
Stop saying you can’t Spring! On the first day of Spring, learn to enter dachang!
On the second day of Spring, you must know several ways that containers register components! Use it to beat the interviewer!
On the third day of Spring, explain the life cycle of beans in detail and leave the interviewer speechless!
Today I’ll explain the underlying use of Spring’s BeanPostProcessor.
Background: What is a BeanPostProcessor? What’s the use?
Spring’s BeanPostProcessor interface runs through all of Spring’s Bean processing. The BeanPostProcessor interface manages all the BeanDefinition (not instantiated) data in the bean factory, and can modify the properties at will.
Let’s start by looking at the classes that implement the BeanPostProcessor interface
You can see from the figure above that there are so many interfaces and classes that implement the BeanPostProcessor interface, Today the key to explain ApplicationContextAwareProcessor, BeanValidationPostProcessor, InitDestoryAnnotationBeanPostProcessor principle. Including ApplicationContextAwareProcessor class is the interface for some types of Aware, into the corresponding attribute values. These components for us the IOC container, it is a rear processor, follow up ApplicationContextAwareProcessor class we found that the post processor is judge we have bean implementation ApplicationContextArea interface, And handle the corresponding logic, which is how all post-processors work.
(the other classes and interfaces shall not discuss here, focus on ApplicationContextAwareProcessor class is how to help the IOC container components. Ps: The words are long, be careful to distinguish between the corresponding classes and interfaces.
A, ApplicationContextAwareProcessor realization analysis
Question: how does ApplicationContextAwareProcessor help us component IOC container?
Answer: Just implement the ApplicationContextAware interface.
Define the entity class plane. Java class
We’ll analyze the source of ApplicationContextAwareProcessor class method
1. Determine if the ApplicationContextAware interface is implemented before the Plane object is created and initialized, and if so, call the invokeAwareInterfaces() method and inject values into it.
The invokeAreaInterfaces() method is used to determine which aware is the bean. If it is ApplicationContextAware, convert the current bean to ApplicationContextAware. Call setApplicationContext() to inject a plane into the IOC container.
3. Debug with debug calls, test case break points:
4. Debug call stack can also be used for analysis.
Ps: Debug can play in ApplicationContextAwareProcessor processor type PostProcessorsBeforeInitialization () method, debug, when the bean is plane type, F5 to follow up, Finally, we return our IOC container applicationContext in the InvokeAwareInterfaces() method.
Second, the BeanValidationPostProcess analysis
This class is mainly used for data verification. After the object is created and the value is assigned to the bean, it is especially used on the Web. Validates the submitted values of the page.
Through the source code can be seen in the BeanValidationPostProcess class 87 and 95 lines, with postProcessBeforeInitialization () and postProcessAfterInitialization () method, These two methods validate the bean before and after initialization, respectively.
Three, InitDestoryAnnotationBeanPostProcessor realization analysis
This class is used to handle @postconstruct and @predeStory in the JSR250 specification.
Define the entity class jeep.java class
For @postconstruct, why is it that once you declare this annotation, you find an init method?
Continuing execution, you can see that the invokeInitMethods() method is invoked using reflection
From the above the debug debugging, InitDestoryAnnotationBeanPostProcessor to handle the call before and after the two annotations are beginning.
Next, let’s take a look at @AutoWired autowiring
Iv. @autoWired Automatic assembly
What is auto-assembly? Autorun: Spring uses dependency injection (DI) to assign dependencies to individual components in the IOC container.
1. Create testController.java, TestService. Java, and TestDao. Java classes and create them in the specified package. Configure the classes to scan and save all these Java objects in the IOC container for management.
2. Create a configuration class, scan and load the beans to the container
3. After the testService. Java class is created, use @AutoWired to inject testDao and print it out
4. Create a test class and compare whether the testDao obtained by TestService is the same as the testDao obtained directly from the container.
The result is clearly the same testDao printed out with the same address
Summary:
Autowired indicates that by default, anno. GetBean (testDao.class) obtains the bean with the ID TestDao from the container and injects it into the bean of TestService.
The usage is as follows:
@autoWired Private testDao testDao; }Copy the code
5. Precautions
5.1 If multiple TestDAOs are found in the container, which testDao will be loaded?
steps
Declare @bean (“testDao2”) in the configuration class
Add TestDao to the Flag attribute and get, set, and toString() methods to tell which bean is loaded.
How do I distinguish TestService from bean with flag=1 from bean with flag=2?
The test steps are as follows:
1. Directly inject testDao into TestService using @AutoWired
The bean id is testDao. By default, the testDao annotated by @reponSitory is found
The test results are:
service… testDao… TestDao [flag=1]
2. What if you must use testDao2 in the container? The operation is as follows:
Just point the bean ID to testDao2
The test results are:
service… testDao… TestDao [flag=2]
TestDao testDao2 (flag=1); TestDao (flag=1); You can use the @autoWired and @Qualifier combination to specify which bean to inject.
The operation is as follows:
Specify that the testDao is loaded using the @qualifier annotation
Test results:
service… testDao… TestDao [flag=1]
4. What happens if there are no TestDaOs in the container?
Comment out @repository and @bean (“testDao2”)
Neither bean is loaded when the container starts (because the annotation is annotated…….).
The test results are as follows:
This is obviously an error, because the attribute in the @Autowired annotation defaults to Required =true. The bean must be found
So what’s the solution?
Set required to false in @AutoWired in TestService, specify that it is not required, and no error will be reported if the bean does not exist in the container.
The test results are as follows:
null
5. Does the @primary annotation specify how the bean is loaded?
(Note: Restore the annotated @repository and @bean (“testDao2”) as shown below)
Important: To verify the loading order of @qualifier and @primary annotations, test the following:
What happens when there are multiple testDAOs in a container and the @qualifier and @primary annotations exist at the same time?
See following: Open @qualifier and @primary annotations.
Test results:
TestDao [flag=1]
unit…. test…. TestDao [flag=2]
Note that @qualifier obtains testDao based on the bean ID specified, regardless of @primary
So what does @primary do? Continue testing…..
Test results:
5.2 In addition to @autowired, are @Resource(JSR250) and @Inject(JSR330) also used?
Comment out Qualifier and Autowired (note: @primary is not commented…… at this point)
Test results:
The effect is the same, but it does not assemble the @primary bean first
Summary: The differences between @Resource and Autowired are as follows:
@Resource, like Autowired, can assemble beans
@ the Resource disadvantages:
① The @primary function is not supported
② @autoWired (Required = false) functionality is not supported
Of course, you can also specify the Bean to inject in TestService as follows
Test results:
5.3 @ Use of Inject automatic assembly:
Note: The difference between @inject and @autowired is as follows:
@Inject, like Autowired, can assemble beans and support @primary, which can be used in non-Spring frameworks.
@Inject Disadvantage: It does not support the function of @AutoWired (Required = false). The third-party package javax.Inject needs to be imported
Operation steps:
Pom.xml imports the javax.inject package
2. Annotate with @inject
Conclusions: @inject does not support Required =false, but primary is supported
Autowired belongs to Spring and cannot be separated from Spring, while @Resource and @Inject are JAVA specifications
I recommend using @autowired
This chapter is rather difficult to understand. You can leave a comment below for discussion.
(Summary from Xiangxue IT)
On day 4 of Spring, BeanPostProcessor source code analysis, thoroughly understand IOC injection and annotation priority issues!
Tomorrow there will be a big chapter, an introduction to the basics of AOP, theory and practice.
Focus on the public account [Java Geek thinking]
Java geek mind
Scan wechat and follow the official account