Spring Boot 系統初始化器


1、Spring Boot 系統初始化器

系統初始化器介紹

SpringFactoriesLoader介紹

系統初始化器原理

 

2、系統初始化器介紹

類名: ApplicationContextinitializer

介紹: Spring容量刷新之前執行的一個回調函數

作用: 向SpringBoot容器中注冊屬性

使用:繼承接口自定義實現

 

 

3、系統初始化器實踐

創建系統初始化器方式一(實現原理:定義在spring.factories 文件中被SpringFactoriesLoader發現注冊)

1)創建初始化器

在包initializer下創建FirstInitializer

/**
 *
 * 第一個系統初始化器
 */
@Order(1)
public class FirstInitializer  implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
        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");
    }
}

  

2) 創建spring.factories 

 

 

內容為:

org.springframework.context.ApplicationContextInitializer=com.example.demo.initialize.FirstInitializer


3) 創建服務類 TestService 
@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("key1");
    }
}

  

4) 在Controller層增加方法

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

  

5) 啟動工程查看效果

可以發現打印了run FirstInitializer

 

 然后調用接口。返回值為之前設置的value1

 

 

創建系統初始化器方式二(實現原理:初始化完畢手動添加)

1)訂單創建初始化器

@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");
    }
}

  

2) SB2Application改成如下

@SpringBootApplication
@MapperScan("com.example.demo.mapper")
public class Sb2Application {

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

}

  

3) 修改Service的test方法

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

 

4)啟動(說明兩個初始化器都已經創建)

. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.6.RELEASE)

run FirstInitializer
run SecondInitializer

 

5)、測試返回結果。返回value2

 

 

創建系統初始化器方式三(實現原理:定義成環境變量被DelegatingApplicationContextInitializer發現注冊)

1)創建初始化器

@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");
    }
}

  

2) 在application.properties 增加

context.initializer.classes=com.example.demo.initializer.ThirdInitializer

 

 

3)、修改TestServer的test方法

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

  

4) 啟動測試

 

 可以發現打印的順序和定義的不一致。第三個ThirdInitializer初始化器優先於第一個和第二個打印出來。

 

使用接口測試,返回value2

 

那springboot初始化器是如何被識別呢,靠的就是SpringFactoriesLoader

springboot初始化器原理: 

初始化SpringApplication  工廠加載機制 SpringFactoriesLoader

 調用run方法: Spring Boot 系統初始化器是如何被調用的,以及實現原理 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM