目录

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: 测试代码三: (测试结果)

spring boot 项目启动 初始化加载数据 springboot启动加载类_java

--> 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 测试结果

spring boot 项目启动 初始化加载数据 springboot启动加载类_spring boot_02

 -> 2.6 @PostConstruct注解

--> 2.6.1 优先级在2.4.1 里 图片如下: 

spring boot 项目启动 初始化加载数据 springboot启动加载类_static_03

--> 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. 文章总结:

实现一个功能有不同的解决方式, 只有不断的尝试, 探索, 寻找到与当前业务更加贴合的技术, 技术是为业务服务的, 制作不易