ApplicationRunner & CommandLineRunner & @PostConstruct & static

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

不是很建议使用这些类
建议:
1:页面按钮(后端读表放入缓存,还可以实现reload/unload等)初始化数据
2:懒加载机制,后端用到时,再去读表+放入缓存
3:如果是某些配置,如:请求url,配置参数,那么一定要写到配置文件里,不要这样启动后再去加载

一、四种实现方式

被调用服务 InitService

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class InitService {
    
    

    public void init() {
    
    
        log.info("InitService");
    }
}

ApplicationRunner

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.concurrent.Executors;

@Slf4j
@Component
public class ApplicationRunnerExtend implements ApplicationRunner {
    
    

    private final InitService initService;

    public ApplicationRunnerExtend(InitService initService) {
    
    
        this.initService = initService;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
    
    
        log.info("-----------ApplicationRunnerExtend-----------");
        Executors.newSingleThreadExecutor().execute(() -> {
    
    
            log.info("开启线程执行");
            initService.init();
        });
    }
}

CommandLineRunner

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class CommandLineRunnerExtend implements CommandLineRunner {
    
    

    private final InitService initService;

    public CommandLineRunnerExtend(InitService initService) {
    
    
        this.initService = initService;
    }

    @Override
    public void run(String... args) throws Exception {
    
    
        log.info("-----------CommandLineRunnerExtend-----------");
        initService.init();
    }
}

@PostConstruct

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Slf4j
@Component
public class PostConstructExtend {
    
    
    private final InitService initService;

    public PostConstructExtend(InitService initService) {
    
    
        this.initService = initService;
    }

    @PostConstruct
    public void init() {
    
    
        log.info("-----------PostConstructExtend-----------");
        initService.init();
    }
}

static

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class StaticExtend {
    
    

    static {
    
    
        InitService initService = new InitService();
        log.info("-----------StaticExtend-----------");
        initService.init();
    }
}

二、执行结果

[           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
[           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 891 ms
[           main] c.e.demo.runner.PostConstructExtend      : -----------PostConstructExtend-----------
[           main] com.example.demo.runner.InitService      : InitService
[           main] com.example.demo.runner.StaticExtend     : -----------StaticExtend-----------
[           main] com.example.demo.runner.InitService      : InitService
[           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
[           main] com.example.demo.TaoDemoApplication      : Started TaoDemoApplication in 21.677 seconds (JVM running for 27.449)
[           main] c.e.demo.runner.ApplicationRunnerExtend  : -----------ApplicationRunnerExtend-----------
[           main] c.e.demo.runner.CommandLineRunnerExtend  : -----------CommandLineRunnerExtend-----------
[           main] com.example.demo.runner.InitService      : InitService
[pool-2-thread-1] c.e.demo.runner.ApplicationRunnerExtend  : 开启线程执行
[pool-2-thread-1] com.example.demo.runner.InitService      : InitService

三、注意异常

InitService中新增方法(会抛异常)

    public void initTwo(){
    
    
        log.info("InitService");
        String str = null;
        str.contains("123");
    }

ApplicationRunner 和 CommandLineRunner虽然是在spring启动成功后再执行的,但如果是执行initTwo,则会因为异常导致启动失败。

建议:
1:异步执行initTwo(),不造成spring启动失败

    public void run(ApplicationArguments args) throws Exception {
    
    
        log.info("-----------ApplicationRunnerExtend-----------");
        Executors.newSingleThreadExecutor().execute(() -> {
    
    
            log.info("开启线程执行");
            initService.initTwo();
        });
    }

2:使用try/catch捕获异常

    @Override
    public void run(String... args) throws Exception {
    
    
        log.info("-----------CommandLineRunnerExtend-----------");
        try {
    
    
            initService.initTwo();
        }catch (Exception e){
    
    
            log.error("异常了!!!");
        }
    }

总结

@PostConstructstatic 不建议用来初始化数据。
他们是在spring启动完成之前执行的,除非必要,不要用这两个去加载初始化数据。

2023年加油加油!

猜你喜欢

转载自blog.csdn.net/qq_37700773/article/details/129208188
今日推荐