目錄
1. 業務場景
-> 1.1 初始化操作
-> 1.2 業務操作
-> 1.3優勢
2. 實作方式(多種方式,不同思想)
-> 2.1 定時排程任務(常用四種方式 task )
--> 2.1.1 Timer(單線程)
--> 2.1.2 scheduledExecutorService(多線程并發執行,線程池)
--> 2.1.3 Spring Task (spring自帶的Task任務排程)
--> 2.1.4 Quartz 定時任務排程架構
-> 2.2 CommandLineRunner代碼實作>>>>>
-> 2.3 ApplicationRunner代碼實作>>>>>>
-> 2.4 InitializingBean: bean初始化之後
--> 2.4.1 執行優先級順序:
-> 2.4.2 spring的Bean執行介紹以及操作方式
---->2.4.2.1: 測試代碼一:
---->2.4.2.2: 測試代碼二:
---->2.4.2.3: 測試代碼三: (測試結果)
--> 2.4.2 代碼實作>>>>>>>>>>>>
-> 2.5 static靜态代碼塊
--> 2.5.1 代碼實作>>>>>>>
--> 2.5.2 測試結果
-> 2.6 @PostConstruct注解
--> 2.6.1 優先級在2.4.1 裡 圖檔如下:
--> 2.6.2 常用使用場景代碼實作>>>>>>>>>>
3. 文章總結:
1. 業務場景
-> 1.1 初始化操作
想通過查詢測試資料庫連結以及第一次建立池連結, 讀取配置檔案等情況
-> 1.2 業務操作
同步資料, 同步緩存資訊, 檢測部分功能是否正常運作等
-> 1.3優勢
避免了人員操作, 僅啟動類加載啟動時執行一次即可
2. 實作方式(多種方式,不同思想)
-> 2.1 定時排程任務(常用四種方式 task )
定時排程任務詳細介紹: -> 暫無
--> 2.1.1 Timer(單線程)
包: java.util.Timer (基本沒用)
--> 2.1.2 scheduledExecutorService(多線程并發執行,線程池)
包: package java.util.concurrent;
--> 2.1.3 Spring Task (spring自帶的Task任務排程)
注解: @Scheduled(corn="表達式") void方法上即可
@EnableScheduling 啟動類添加
ps: 建議異步執行 不然預設是同步執行(一個線程)
--> 2.1.4 Quartz 定時任務排程架構
添加依賴: springboot版本
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
核心: 類繼承 QuartzJobBean, 詳情請看下文
-> 2.2 CommandLineRunner代碼實作>>>>>
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 類加載時自動執行
* @author pzy
* @version 0.1.0
*/
@Order(1) //執行優先級順序
@Slf4j
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Value("${spring.auto.user.isAutoCheck:false}")
private Boolean isAutoCheck;
@Autowired
private Controller controller; //直接執行即可 注入bean後使用方法
@Override
public void run(String... args) throws Exception {
if(isAutoCheck){
log.info("===> MyCommandLineRunner 執行成功 <===")
}
}
}
-> 2.3 ApplicationRunner代碼實作>>>>>>
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 類加載時自動執行 方法二
* @author pzy
* @version 0.1.0
*/
@Slf4j
@Component //想使用打開即可
@Order(2) //如果多個自定義的 ApplicationRunner ,用來标明執行的順序
public class ApplicationRunnerStartService implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
log.info("==> 測試初始化 <===");
}
}
-> 2.4 InitializingBean: bean初始化之後
--> 2.4.1 執行優先級順序:
靜态代碼塊> 構造代碼塊> Constructor > @PostConstruct > InitializingBean > init-method
-> 2.4.2 spring的Bean執行介紹以及操作方式
Spring 的 Bean 是有生命周期的, Bean在初始化完成後以及 Bean 銷毀前執行特定的操作,常用的設定方式有以下三種:
1. 通過實作 InitializingBean/DisposableBean 接口來定制初始化之後/銷毀之前的操作方法
2. 通過 元素的 init-method/destroy-method屬性指定初始化之後 /銷毀之前調用的操作方法
3. 方法加@PostConstruct 或@PreDestroy注解 表示是在初始化之後還是銷毀之前調用
---->2.4.2.1: 測試代碼一:
public class OrderCtrlTest {
static {
System.out.println("我是一個靜态代碼塊");
}
{
System.out.println("我是一個構造代碼塊");
}
public OrderCtrlTest() {
System.out.println("我是構造函數");
}
public static void main(String[] args) {
OrderCtrlTest orderCtrlTest = new OrderCtrlTest();
//執行結果:
//我是一個靜态代碼塊
//我是一個構造代碼塊
//我是構造函數
}
}
---->2.4.2.2: 測試代碼二:
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
/**
* 類加載時自動執行 方法三
* @author pzy
* @version 0.1.0
*/
@Slf4j
@Component
public class AutoInitializingRunner implements InitializingBean {
public AutoInitializingRunner() {
log.info("==> 1: AutoInitializingRunner的構造方法");
}
@Bean
public void initMethod() {
log.info("==> 3: initMethod 方法");
}
@Override
public void afterPropertiesSet() {
log.info("==> 2: 執行InitializingBean的唯一重寫方法");
}
}
---->2.4.2.3: 測試代碼三: (測試結果)
--> 2.4.2 代碼實作>>>>>>>>>>>>
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
/**
* 類加載時自動執行 方法三
* @author pzy
* @version 0.1.0
*/
@Slf4j
@Component
public class AutoInitializingRunner implements InitializingBean {
@Override
public void afterPropertiesSet() {
log.info("==> 1: 執行InitializingBean的唯一重寫方法");
}
}
-> 2.5 static靜态代碼塊
--> 2.5.1 代碼實作>>>>>>>
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableScheduling
//@EnableRabbit
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "*")
@EnableTransactionManagement
@ComponentScan(basePackages={"*"})
@MapperScan("*")
@Slf4j
@SpringBootApplication
public class AaaApplication {
static{
System.out.println("靜态代碼塊執行部分業務可以!");
log.info("===> 靜态代碼塊執行部分業務可以!");
}
public static void main(String[] args) {
SpringApplication.run(AaaApplication.class, args);
}
}
--> 2.5.2 測試結果
-> 2.6 @PostConstruct注解
--> 2.6.1 優先級在2.4.1 裡 圖檔如下:
--> 2.6.2 常用使用場景代碼實作>>>>>>>>>>
@Value("${spring.redis.host}")
public String ip;
@Value("${spring.redis.password}")
public String redisPassword;
public static String IP;
public static String REDIS_PASSWORD;
@PostConstruct
public void init() {
IP = ip;
REDIS_PASSWORD = redisPassword;
}
3. 文章總結:
實作一個功能有不同的解決方式, 隻有不斷的嘗試, 探索, 尋找到與目前業務更加貼合的技術, 技術是為業務服務的, 制作不易