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 Bean
s 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 13
public 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
Bean
s that implementCommandLineRunner
can be adjusted based on the@Order
annotation on theBean
. -
The
run
method 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/