SpringBoot's startup extension point ApplicationContextInitializer

User 3147702 2022-09-23 09:52:08 阅读数:533

springbootstartupextensionpointapplicationcontextinitializer

1. 引言

此前的文章中,我们详细介绍了 Spring Six extension points are reserved that can be used to extend the code,so that we can be there Spring In the startup phase, add the business startup code we need:

添加 SpringBoot Six ways to customize your startup code(上)

添加 SpringBoot Six ways to customize your startup code(下)

事实上,Spring There are many extension points,Just usually if we just add business startup code,Or initialize and parse the running parameters,Using the above six extension points can already meet the needs.

但是,If we want to fundamentally change something Spring 的默认行为,例如修改 Context 中的属性,Or to change bean The create-load behavior of ,这时,我们就必须在 SpringBoot Extended early in the life cycle.

SpringBoot Such extension points are reserved for us,It is what this article will cover ApplicationContextInitializer.

2. ApplicationContextInitializer

SpringBoot 在 Spring 的基础上,遵循约定大于配置原则,Added a lot of autowiring mechanisms.Let's give components to others,只需要按照 SpringBoot The specification implements our own extension,Others can autowire our components without any configuration.ApplicationContextInitializer It is the extension point that can be autowired like this.

SpringBoot 会在完成 ConfigurableApplicationContext 的构建后,before the container refreshes,Automatic calls have been wired in SpringBoot 容器的 ApplicationContextInitializer 接口实现类,执行它的 initialize 方法.

ApplicationContextInitializer 接口的定义如下:

 public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {
void initialize(C var1);
}

如果这个接口有多个实现类,SpringBoot 支持通过 @Order 注解或实现 Ordered The interface specifies the execution priority of each implementing class.

3. Add three ways to start

If we implement the above ApplicationContextInitializer 接口,How to add our implementation class to SpringBoot is starting?有三种方法.

3.1 在 main 方法中调用

通过 SpringApplication 对象的 addInitializers 方法,可以添加多个 ApplicationContextInitializer 实现类:

 @SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(MySpringBootApplication.class);
application.addInitializers(new MyApplicationContextInitializer());
application.run(args);
}
}

3.2 在 classpath configured in the configuration file below

SpringBoot 启动时,会扫描 classpath,寻找 application.properties 配置,to find the relevant components that need to be called during the startup process.

在这个配置文件中,加入 ApplicationContextInitializer 实现类的配置,就可以实现让 SpringBoot The implementation class is loaded automatically.

 context.initializer.classes=org.springframework.boot.demo.common.MyApplicationContextInitializer

3.3 SpringBoot 的 SPI 扩展 -- META-INF/spring.factories 中配置

在 classpath 下的 META-INF/spring.factories The corresponding implementation class can also be configured in the configuration ApplicationContextInitializer Implements automatic loading and startup of classes:

 org.springframework.context.ApplicationContextInitializer=org.springframework.boot.demo.common.MyApplicationContextInitializer

4. 实例:利用 ApplicationContextInitializer 实现 bean manual loading of

在 SpringBoot 中,创建 bean 有多种方法:

  1. 通过 xml bean The method described by the label;
  2. @Bean 注解的方法;
  3. 通过 @Component、@Service、@Controler、@Repository 注解的类;
  4. 通过 @Import 注解;
  5. 实现 ImportSelector、ImportBeanDefinitionRegistrar、EnableImportSelector 接口;
  6. 通过 beanFactory 手动注入.

We are already familiar with these methods,但有时,We want to construct one entirely ourselves bean 对象,And because it is subject to other bean 的依赖,It needs to be loaded at the initial stage of startup SpringBoot 的上下文环境中,这时,通过 ApplicationContextInitializer To achieve is a good choice.

The following example demonstrates the pass ApplicationContextInitializer The implementation class is created bean:

 public class BootInitializer implements ApplicationContextInitializer<GenericApplicationContext> {
@Override
public void initialize(GenericApplicationContext genericApplicationContext) {
String beanName = "BootInitializeBean";
Object beanObject = generateBeanObject(beanName);
genericApplicationContext.registerBean(beanName, beanObject.getClass(), (Supplier) () -> beanObject, bd -> {
bd.setAutowireCandidate(false);
bd.setLazyInit(true);
});
}
}

在这个例子中,The callback parameter was called GenericApplicationContext 对象的 registerBean 方法,指定了 bean 的 name、类型、对象以及 bean 属性.

It is worth mentioning the fourth parameter,该参数是可选的,它是用来指定 bean 属性的 BeanDefinitionCustomizer 接口实现.

当然了,这只是一个例子,除此以外,ApplicationContextInitializer There are multiple uses,例如将 beanFactory Replace with an object of your own implementation,to achieve what you want unique bean loading method, etc.

copyright:author[User 3147702],Please bring the original link to reprint, thank you. https://en.javamana.com/2022/266/202209230926200494.html