欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

springboot2啟動(dòng)時(shí)執(zhí)行,初始化(或定時(shí)任務(wù))servletContext問(wèn)題

 更新時(shí)間:2023年01月12日 10:56:40   作者:亦寒2017  
這篇文章主要介紹了springboot2啟動(dòng)時(shí)執(zhí)行,初始化(或定時(shí)任務(wù))servletContext問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

springboot2啟動(dòng)時(shí)執(zhí)行,初始化(或定時(shí)任務(wù))servletContext

需求:springboot 啟動(dòng)后自動(dòng)執(zhí)行,初始化數(shù)據(jù),并將數(shù)據(jù)放到 servletContext 中。

首先,不可使用 ServletContextListener 即不能用 @WebListener ,因?yàn)?servlet 容器初始化后,spring 并未初始化完畢,不能使用 @Autowired 注入 spring 的對(duì)象。

代碼如下:

可以實(shí)現(xiàn) ApplicationListener

@Component
public class SettingDataInitListener implements ApplicationListener<ContextRefreshedEvent> {
? ? @Override
? ? public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
? ? ? ? WebApplicationContext webApplicationContext =?
? ? ? ? ? ? (WebApplicationContext)contextRefreshedEvent.getApplicationContext();
? ? ? ? ServletContext servletContext = webApplicationContext.getServletContext();
? ? ? ? servletContext.setAttribute("key", "value");
? ? }
}

使用注解注入

service類里注入 servletContext

@Autowired private ServletContext servletContext;

service類里要啟動(dòng)執(zhí)行的方法加上注解

@PostConstruct

在定時(shí)任務(wù)里,也可以注入 servletContext,進(jìn)行定時(shí)操作

@Component
public class MyTask {
? ? @Autowired
? ? private ServletContext servletContext;

? ? // 秒 分 時(shí) 日 月 周
? ? @Scheduled(cron = "0 * * * * *")
? ? public void resetDays() {
? ? ? ? // servletContext
? ? }
}

springboot啟動(dòng)時(shí)初始化數(shù)據(jù)的幾種方式

在我們用springboot搭建項(xiàng)目的時(shí)候,經(jīng)常碰到在項(xiàng)目啟動(dòng)時(shí)初始化一些字典數(shù)據(jù)、地市數(shù)據(jù)、等各類需求,針對(duì)這種需求Spring與Spring boot為我們提供了以下幾種方案供我們選擇:

  • springboot提供的ApplicationRunner與CommandLineRunner接口
  • Spring Bean初始化的init-method、PostConstruct注解、

InitializingBean、BeanPostProcessor接口

Spring的事件機(jī)制: 實(shí)現(xiàn) ApplicationListener 接口

一、ApplicationRunner與CommandLineRunner

如果需要在SpringApplication啟動(dòng)時(shí)執(zhí)行一些特殊的代碼,可以通過(guò)實(shí)現(xiàn)ApplicationRunner或CommandLineRunner接口,這兩個(gè)接口都提供單一的run方法,且run方法僅在SpringApplication.run(…)完成之前調(diào)用。

區(qū)別:參數(shù)不一樣,CommandLineRunner的參數(shù)是最原始的參數(shù),沒(méi)有進(jìn)行任何處理,ApplicationRunner的參數(shù)是ApplicationArguments

ApplicationRunner接口只需要自己創(chuàng)建類實(shí)現(xiàn)ApplicationRunner接口

/**
?* @author 重慶阿湯哥
?* @Description: 測(cè)試
?* @date 2021/11/26 ?
?*/
@Component
@Slf4j
public class ApplicationRunnerTest implements ApplicationRunner {

? ? @Override
? ? public void run(ApplicationArguments args) throws Exception {
? ? ? ? log.info("ApplicationRunner init data.....");
? ? }
}

CommandLineRunner

對(duì)于這個(gè)接口而言,我們可以通過(guò)Order注解或者使用Ordered接口來(lái)指定調(diào)用順序,@Order()中的值越小,優(yōu)先級(jí)越高

/**
?* @author 重慶阿湯哥
?* @Description: 測(cè)試
?* @date 2021/11/26 ?
?*/
@Component
@Slf4j
@Order(1)
public class CommandLineRunnerTest implements CommandLineRunner {

? ? @Override
? ? public void run(String... args) throws Exception {
? ? ? ? log.info("CommandLineRunner init data.....");
? ? }
}

二、Spring Bean初始化的InitializingBean,init-method和PostConstruct

InitializingBean接口、BeanPostProcessor接口

InitializingBean接口為bean提供了初始化方法的方式,它只包括afterPropertiesSet()方法。

在spring初始化bean的時(shí)候,如果bean實(shí)現(xiàn)了InitializingBean接口,在對(duì)象的所有屬性被初始化后之后才會(huì)調(diào)用afterPropertiesSet()方法

/**
?* @author 重慶阿湯哥
?* @Description: 測(cè)試
?* @date 2021/11/26 ?
?*/
@Component
@Slf4j

@Component
public class InitialingzingBeanTest implements InitializingBean {

? ? @Override
? ? public void afterPropertiesSet() throws Exception {
? ? ? ?log.info("InitializingBean init....");
? ? }
}

@PostConstruct

/**
?* @author 重慶阿湯哥
?* @Description: 測(cè)試
?* @date 2021/11/26 ?
?*/
@Component
@Slf4j
public class DynamicRouteMonitor {
? ?
? ? @PostConstruct
? ? public void init() {
? ? ? ? log.info("gateway route init...");
? ? ? ? }
}

BeanPostProcessor接口

可以用于判斷某些特定類加載完成后才能初始化數(shù)據(jù)的場(chǎng)景,只需要自己實(shí)現(xiàn)該接口中的方法進(jìn)行前置條件判斷

public interface BeanPostProcessor {
? ? @Nullable
? ? default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
? ? ? ? return bean;
? ? }

? ? @Nullable
? ? default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
? ? ? ? return bean;
? ? }
}

三、Spring的事件機(jī)制

在Spring中,默認(rèn)對(duì)ApplicationEvent事件提供了如下支持:

  • ContextStartedEvent:ApplicationContext啟動(dòng)后觸發(fā)的事件
  • ContextStoppedEvent:ApplicationContext停止后觸發(fā)的事件
  • ContextRefreshedEvent:ApplicationContext初始化或刷新完成后觸發(fā)的事件;也就是容器初始化完成后調(diào)用。
  • ContextClosedEvent:ApplicationContext關(guān)閉后觸發(fā)的事件;如web容器關(guān)閉時(shí)自動(dòng)會(huì)觸發(fā)spring容器的關(guān)閉。甚至大家聽(tīng)說(shuō)過(guò)的鉤子程序都是調(diào)用ctx.registerShutdownHook()進(jìn)行注冊(cè)虛擬機(jī)關(guān)閉。

利用ContextRefreshedEvent事件進(jìn)行初始化操作

/**
?* @author 重慶阿湯哥
?* @Description:容器初始化完整后初始字典數(shù)據(jù)
?* @date 2021/11/26 ?10:51
?*/
@Component
public class ApplicationStartup implements ApplicationListener<ContextRefreshedEvent> {
? ? public void onApplicationEvent(ContextRefreshedEvent event) {
? ? ? ? //在容器加載完畢后獲取dao層來(lái)操作數(shù)據(jù)庫(kù)
? ? ? ? ISysDictTypeService sysDictTypeService = (ISysDictTypeService) event.getApplicationContext().getBean(ISysDictTypeService.class);

? ? ? ? sysDictTypeService.initDict();

? ? ? ? IProvCityService provCityService = (IProvCityService) event.getApplicationContext().getBean(IProvCityService.class);
? ? ? ? provCityService.initProvCity();

? ? }

? ? @Override
? ? protected Object clone() throws CloneNotSupportedException {
? ? ? ? return super.clone();
? ? }
}

這幾種方式都可以滿足我們?nèi)粘i_(kāi)發(fā)的需求,針對(duì)具體場(chǎng)景使用對(duì)應(yīng)的方案,在微服務(wù)應(yīng)用中使用也較廣泛。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論