目录
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. 文章总结:
实现一个功能有不同的解决方式, 只有不断的尝试, 探索, 寻找到与当前业务更加贴合的技术, 技术是为业务服务的, 制作不易