springboot2-ApplicationContextInitializer系统初始化器3种实现

step1: 实现 ApplicationContextInitializer 接口

step2: resources下创建: META-INF/spring.factories

resources下创建: META-INF/spring.factories, 配置key和value分别为: 接口类=实现类

代码示例

(1). 实现 ApplicationContextInitializer

package com.niewj.fileman.initialized;

import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author weijun.nie
 * @Date 2020/4/27 8:00
 * @Version 1.0
 */
@Order(1)
public class FirstACInitializer implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
        Map<String,Object> map = new HashMap<>();
        map.put("k1", "keyfirst");

        MapPropertySource firstInitializer = new MapPropertySource("firstInitializer", map);
        environment.getPropertySources().addLast(firstInitializer);
        System.out.println("......FirstInitializer[ApplicationContextInitializer]......");
    }
}

(2). 配置(创建文件): spring.factories: src/main/resources/META-INF/spring.factories

org.springframework.context.ApplicationContextInitializer=com.niewj.fileman.initialized.FirstACInitializer

提供一个service中提供获取方法:

package com.niewj.fileman.service;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * @Author weijun.nie
 * @Date 2020/4/27 7:50
 * @Version 1.0
 */
@Component
public class ACInitializerService implements ApplicationContextAware {

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

    public String findKey(String key){
        return applicationContext.getEnvironment().getProperty(key);
    }
}

控制器:

package com.niewj.fileman.controller;

import com.niewj.fileman.service.ACInitializerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/acInitializer")
public class ACInitializerController {

    @Autowired
    private ACInitializerService ACInitializerService;

    @RequestMapping("/props/{key}")
    @ResponseBody
    public String getByKey(@PathVariable("key") String key) {
        return ACInitializerService.findKey(key);
    }
}

2. 第二种:自定义 SpringApplication 加初始化器

step1: 实现 ApplicationContextInitializer 接口

step2: main方法中 自己实例化 SpringApplication 设置初始化器

代码示例

package com.niewj.fileman.initialized;

import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author weijun.nie
 * @Date 2020/4/27 8:00
 * @Version 1.0
 */
@Order(2)
public class SecondACInitializer implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        // 1. 获取到 Environment
        ConfigurableEnvironment environment = applicationContext.getEnvironment();

        // PropertySource: MapPropertySource
        Map<String, Object> map = new HashMap<>();
        map.put("2key1", "2value1");
        MapPropertySource mapPropSource = new MapPropertySource("SecondACInitializer-map", map);

        // 2. 调用 environment获取属性源(PropertySources),
        //  将 map 的PropertySource 加入 environment:
        environment.getPropertySources().addLast(mapPropSource);

        System.out.println("......SecondACInitializer[ApplicationContextInitializer]......");
    }
}

step2: main方法:

package com.niewj.fileman;

import com.niewj.fileman.initialized.SecondACInitializer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Sb2Application {

    public static void main(String[] args) {
//        SpringApplication.run(FilemanApplication.class, args);

        SpringApplication application = new SpringApplication(Sb2Application.class);
        application.addInitializers(new SecondACInitializer());
        application.run(args);
    }
}

控制台输出:

……FirstInitializer[ApplicationContextInitializer]……
……SecondACInitializer[ApplicationContextInitializer]……

浏览器访问: http://localhost:9999/acInitializer/props/2key1

2value1


3. 第三种:在 application.properties 配置初始化器:

step1: 实现 ApplicationContextInitializer 接口

step2: 在application.properties中配置context.initializer.classes属性设置初始化器

代码示例

package com.niewj.fileman.initialized;

import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author weijun.nie
 * @Date 2020/4/27 8:00
 * @Version 1.0
 */
@Order(3)
public class ThirdACInitializer implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        // 1. 获取到 Environment
        ConfigurableEnvironment environment = applicationContext.getEnvironment();

        // PropertySource: MapPropertySource
        Map<String, Object> map = new HashMap<>();
        map.put("3key1", "3value1");
        MapPropertySource mapPropSource = new MapPropertySource("ThirdACInitializer-map", map);

        // 2. 调用 environment获取属性源(PropertySources),
        //  将 map 的PropertySource 加入 environment:
        environment.getPropertySources().addLast(mapPropSource);

        System.out.println("......ThirdACInitializer[ApplicationContextInitializer]......");
    }
}

控制台输出:

……ThirdACInitializer[ApplicationContextInitializer]……
……FirstInitializer[ApplicationContextInitializer]……
……SecondACInitializer[ApplicationContextInitializer]……

浏览器访问:http://localhost:9999/acInitializer/props/3key1:

3value1

4. 小结: 设置初始化器的3种方法:

4.1 首先, 都要实现 ApplicationContextInitializer接口:

4.2 方法1:

在src/main/resources下创建 META-INF/spring.factories, 然后配置属性 org.springframework.context.ApplicationContextInitializer=com.niewj.fileman.initialized.FirstACInitializer

4.3 方法2:

在main方法中替换SpringApplication.run(args)为:

SpringApplication application = new SpringApplication(App.class); 
application.addInitializers(new SecondACInitializer());
application.run(args);

4.4 方法3:

application.properties 中配置

context.initializer.classes=context.initializer.classes=com.niewj.fileman.initialized.ThirdACInitializer

5. 小结(2): @Order(x):

Order对application.properties中的配置无感: application.properties中的会优先加载;
然后另外两种方式设置的, x值小的先加载!


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 hi@niewj.com

×

喜欢就点赞,疼爱就打赏