We often need to do some hook actions when the container starts, such as registering message consumers, listening to configurations, etc. Today we will summarize the 7 startup extensions that SpringBoot leaves to developers.
Container refresh completion extension point
1.ApplicationListener<ContextRefreshedEvent>
Anyone familiar with Spring must know that a successful container refresh means that all Bean initialization has been completed, and when the container is refreshed Spring will call the onApplicationEvent method of all Beans that implement ApplicationListener<ContextRefreshedEvent> in the container. onApplicationEvent` method, which the application can use to listen for container initialization completion events.
|
|
This extension point needs extra attention when used in the web container. In web projects (such as spring mvc), there are two containers, one is the root application context and the other is our own context (as a sub-container of the root application context as a sub-container of root application context). If we write it in this way, the onApplicationEvent method will be executed twice. The solution to this problem is as follows.
|
|
Advanced usage
Of course there is a more advanced use of this extension: Custom Events, which can be implemented as an observer pattern at minimal cost with the help of Spring.
-
First customize an event.
1 2 3 4 5 6 7 8 9 10 11 12 13public class NotifyEvent extends ApplicationEvent { private String email; private String content; public NotifyEvent(Object source) { super(source); } public NotifyEvent(Object source, String email, String content) { super(source); this.email = email; this.content = content; } // 省略getter/setter方法 } -
Register an event listener
-
publish event
1 2 3 4 5 6 7 8 9 10 11 12@RunWith(SpringRunner.class) @SpringBootTest public class ListenerTest { @Autowired private WebApplicationContext webApplicationContext; @Test public void testListener() { NotifyEvent event = new NotifyEvent("object", "abc@qq.com", "This is the content"); webApplicationContext.publishEvent(event); } } -
Executing the unit test you can see that the address and the content of the email are printed out.
2. CommandLineRunner interface
When the container context is initialized, SpringBoot will also call all run methods that implement the CommandLineRunner interface, and the following code will do the same thing as above.
|
|
There are two additional points to note about the use of this extension point.
-
The execution order of multiple
Beans that implementCommandLineRunnercan be adjusted based on the@Orderannotation on theBean. -
The
runmethod can accept parameters from the console, which is more flexible than theApplicationListener<ContextRefreshedEvent>extension.
3. ApplicationRunner interface
This extension is similar to the CommandLineRunner interface extension of SpringBoot, except that the accepted argument is an ApplicationArguments class that provides better encapsulation of the console input arguments, starting with -- is considered an argument with options, otherwise it is a normal argument.
|
|
For example.
|
|
Bean initialization completion extension point
The previous section summarizes the extension points for container initialization. In some scenarios, such as listening to messages, we want to register listeners immediately after Bean initialization, rather than waiting until the entire container is refreshed, and Spring leaves enough extension points for this scenario as well.
1. @PostConstruct annotation
The @PostConstruct annotation is placed on the methods of a Bean, and the methods modified by @PostConstruct are called immediately after the initialization of the Bean.
|
|
2. InitializingBean interface
The usage of InitializingBean is basically the same as @PostConstruct, except that the corresponding Bean needs to implement the afterPropertiesSet method.
|
|
3. Initialization methods for @Bean annotations
The initialization method can be specified when injecting a Bean with @Bean.
Definition of Bean
Bean injection
4. Injection via constructor
Spring also supports injection via constructor, we can write the code in the constructor and achieve the same purpose.
|
|
Bean initialization completion extension point execution order?
A simple test can be used to.
|
|
Output after instantiating this Bean.
Reference http://www.enmalvi.com/2022/05/21/springboot-start/