SpringBoot源码学习之系统初始化器

2 篇文章 0 订阅
2 篇文章 0 订阅

SpringBoot系统初始化器

一、实现初始化器的3中方法

我们在项目目录下建立目录initializer。实现初始化器我们需要去继承ApplicationContextInitializer接口,并且重写initialize方法。
在这个目录下我们建立我们的initializer,然后再用三种方法去初始化它。

方式1:在initializer下建立FirstInitializer.java文件,在spring.factories配置文件中去初始化,内容如下。

@Order(1)
public class FirstInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
        environment.setRequiredProperties("mooc");
        Map<String, Object> map = new HashMap<>();
        map.put("key1", "value1");
        MapPropertySource mapPropertySource = new MapPropertySource("firstInitializer", map);
        environment.getPropertySources().addLast(mapPropertySource);
        System.out.println("run firstInitializer");
    }
}

接着我们在resources目录下建立META-INF文件夹,并在其中建立文件 spring.factories,这个文件是我们用来初始化FirstInitializer。
内容:

org.springframework.context.ApplicationContextInitializer=com.mooc.sb2.initializer.FirstInitializer

方式2:在initializer下建立SecondInitializer.java文件,改写项目启动类方法,在启动类中初始化,内容如下。

@Order(2)
public class SecondInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
        Map<String, Object> map = new HashMap<>();
        map.put("key2", "value2");
        MapPropertySource mapPropertySource = new MapPropertySource("secondInitializer", map);
        environment.getPropertySources().addLast(mapPropertySource);
        System.out.println("run secondInitializer");
    }
}

然后我们改写springboot的启动类Sb2Application.class代码,在启动方法中去初始化。

public class Sb2Application {
    public static void mian (String[] args) {
        SpringApplication springApplication = new SpringApplication(Sb2Application.class);
        springApplication.addInitializers(new SecondInitializer());
        springApplication.run(args);
     }
}

方法3:建立ThirdInitializer.java文件,我们在application.properties配置文件中初始化。

@Order(3)
public class ThirdInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
        Map<String, Object> map = new HashMap<>();
        map.put("key3", "value3");
        MapPropertySource mapPropertySource = new MapPropertySource("thirdInitializer", map);
        environment.getPropertySources().addLast(mapPropertySource);
        System.out.println("run thirdInitializer");
    }
}

application.properties文件中添加:

context.initializer.classes=com.mooc.sb2.initializer.Thirdinitializer

以上就是我们实现三种初始化的方法。可以进行测试。

二、验证自定义的初始化器

编写service类和controller类去获取上下文,得到我们初始化器中初始化的内容。其中获取的property名字可以是:key1、key2或key3,对应着三种初始化的方式代码。
service层实现:

@Component
public class TestService implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public String test() {
        return applicationContext.getEnvironment().getProperty("key3");
    }

}

controller层实现:

@Controller
@RequestMapping("/demo")
public class DemoController {
    @Autowired
    private TestService testService;

    @RequestMapping("test")
    @ResponseBody
    public String test() {
        return testService.test();
    }
}

我们启动springboot后在浏览器端输入localhost:8080/demo/test,就会出现value1、value2或value3,那么就初始化成功。

三、3种初始化实现方式注意点

  1. 都要实现ApplicationContextInitializer接口;
  2. Order值越小越先执行;
  3. application.properties中定义的优先于其它方式;

四、面试问题

1.介绍SpringFactoriesLoader ?
springboot工厂的加载类,springboot用它来完成扩展点实现的展露。

2.SpringFactoriesLoader如何加载工厂类?
通过读取指定路径下的指定文件,把他们读取成一个Property对象,然后依次去遍历文件内容,组装成类名和对象实现,通过order进行排序。

3.系统初始化器的作用?
是springboot容器的回调接口,通过它向springboot容器中定义属性。

4.系统初始化器调用时机?
在springboot的run方法中调用的。

5.如何自定义实现系统初始化器?
文章上面三种方法。

6.自定义初始化器有哪些注意事项?
order值的排序问题,以及不同的初始化实现方法让order值失效(比如pplication.properties中定义的优先于其它方式;)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值