When we think of spring, we probably think of IOC (Inversion of Control) and AOP (Facet Programming).
Yes, they are the cornerstone of spring, thanks to their excellent design, which allows spring to stand out from many excellent frameworks.
In addition, in the process of using spring, have we found that its scalability is very strong. Because of this advantage, spring has a strong ability to tolerate, so that many third-party applications can easily throw themselves into the arms of spring. For example: rocketmq, mybatis, reddis, etc.
Today I will talk to you about the 11 most commonly used extension points in Spring.
Spring mvc interceptor root spring interceptor in contrast to the root spring interceptor, which can get web object instances such as HttpServletRequest and HttpServletResponse.
The top-level interface of the spring mvc interceptor is: HandlerInterceptor, which contains three methods:
For our general situation, we will use the HandlerInterceptor interface implementation class HandlerInterceptorAdapter class.
If you have a scenario of permission authentication, logging, and statistics, you can use this interceptor.
The first step is to inherit the HandlerInterceptorAdapter class definition interceptor:
Second, register the interceptor with the spring container:
In the third step, when requesting an interface, spring mvc can automatically intercept the interface through the interceptor and verify the permissions.
In our day-to-day development, we often need to get a bean from a Spring container, but do you know how to get a Spring container object?
Implement the BeanFactory Aware interface and then override the setBeanFactory method to get the spring container object from that method.
Implementing the ApplicationContextAware interface and then overriding the setApplicationContext method also gets the spring container object from that method.
In the past, when we developed the interface, if there was an exception, in order to give the user a more friendly prompt, for example:
If you do not do anything to process the request add interface results in a direct error:
what? Can the user see the error message directly?
This interaction gives the user a very poor experience, and to solve this problem, we usually catch exceptions in the interface:
After the interface is modified, when an exception occurs, it will prompt: “data abnormality”, which is more user-friendly.
Looks pretty good, but there’s a problem…
If it’s just one interface, it’s fine, but if there are hundreds or thousands of interfaces in the project, do you have to add exception catching code?
The answer is no, and global exception handling comes in handy: RestControllerAdvice.
Only the exception situation needs to be handled in the handleException method, which can be used with confidence in the business interface, and there is no longer a need to catch the exception (someone has handled it uniformly). It’s really cool.
spring currently supports 3 types of converters:
These three types of converters use different scenarios, we take Converter as an example. Suppose: In the entity object that receives the parameters in the interface, there is a field of type Date, but the actual parameter is the string type: 2021-01-03 10:20:15, how to deal with it?
The first step is to define an entity User:
In the second step, implement the Converter interface:
In the third step, inject the newly defined type converter into the spring container:
The fourth step is to call the interface
When you request an interface, the registerDate field in the User object is automatically converted to the Date type.
Sometimes we need to introduce other classes in one configuration class, and the imported classes are added to the spring container. This can be done using @Import annotations.
If you’ve looked at its source code, you’ll see that the introduced classes support three different types.
But I think it’s best to separate the normal class from the configuration class of the @Configuration annotation, so there are four different types listed:
This ingestion is the simplest, and the introduced class is instantiated with a bean object.
By introducing Class A @Import annotations, spring can automatically instantiate the A object and then inject it with @Autowired annotations where needed:
Isn’t that surprising? You can instantiate a bean without adding @Bean annotations.
This approach to introduction is the most complex because @Configuration annotations also support a variety of combined annotations, such as:
By introducing the configuration class of the @Import annotation by @Configuration annotation, the classes introduced by the relevant annotations of the configuration class @Import, @ImportResource, @PropertySource, etc. will be recursively introduced and all at once.
This approach to ingestion requires the implementation of the ImportSelector interface:
The advantage of this approach is that the selectImports method returns an array, which means that multiple classes can be brought in at the same time, which is still very convenient.
This approach to introduction requires the implementation of the ImportBeanDefinitionRegistrar interface:
This method is the most flexible, you can get the BeanDefinitionRegistry container registration object in the registerBeanDefinitions method, you can manually control the creation and registration of BeanDefinition.
Sometimes we need to customize some additional functions at project startup, such as: loading some system parameters, completing initialization, warming up the local cache, etc., what to do?
The good news is that Springboot offers:
These two interfaces help us achieve the above requirements.
Their usage is still quite simple, take the ApplicationRunner interface as an example:
Implement the ApplicationRunner interface, override the run method, and implement your own custom requirements in that method.
If there are multiple classes in the project that implement the ApplicationRunner interface, how do they specify the order of execution?
The answer is to use the @Order(n) annotation, the smaller the value of n, the first execution. Of course, you can also specify the order by @Priority annotations.
Before Spring IOC instantiates the bean object, it needs to read the relevant properties of the bean, save it to the beanDefinition object, and then instantiate the bean object through the BeanDefinition object.
What if you want to modify properties in the BeanDefinition object?
A: We can implement the BeanFactoryPostProcessor interface.
In the postProcessBeanFactory method, you can get the related object of BeanDefinition and modify the properties of that object.
Sometimes, you want to implement some of your own logic before and after initializing the bean.
This is where it works: the BeanPostProcessor interface.
The interface currently has two methods:
For example:
If a User object exists in spring, set its userName to: Susanshu Technique.
In fact, the annotations we often use, such as @Autowired, @Value, @Resource, @PostConstruct, etc., are implemented through AutowiredAnnotationBeanPostProcessor and CommonAnnotationBeanPostProcessor.
At present, spring uses more methods to initialize beans as follows:
Add @PostConstruct annotations to the methods that need to be initialized so that there is the ability to initialize.
Implement the InitializingBean interface and override the afterPropertiesSet method, where initialization can be done.
Sometimes, we need to do some extra work before closing the spring container, such as closing the resource file.
At this point, you can implement the DisposableBean interface and override its destroy method:
This way the spring container is called before it is destroyed to do some extra work.
Typically, we implement both the InitializingBean and DisposableBean interfaces, overriding the initialization method and the destruction method.
We all know that spring supports only two types of scopes by default:
The spring web has expanded Scope to add:
Even so, some scenarios did not meet our requirements.
For example, what if we want to get a bean from the spring container in the same thread and all the same object?
This requires a custom scope.
The first step is to implement the Scope interface:
The second step is to inject the newly defined Scope into the spring container:
The third step uses the newly defined Scope:
If this article is helpful to you, or inspired, help scan the QR code to pay attention to it, your support is the biggest motivation for me to keep writing.
Ask for one click and three links: like, forward, watching.
Pay attention to the public number: [Su San said technology], reply in the public account: interview, code artifact, development manual, time management has excellent fan benefits, and reply: Jia Qun, you can communicate and learn with the seniors of many BAT manufacturers.