Springboot 初始化

本文介绍了在Spring Boot中进行初始化的三种常见方法:1) 使用`static`关键字,静态属性和方法在类加载时初始化;2) 实现`CommandLineRunner`接口,在启动时执行`run()`方法进行数据初始化;3) 使用`@PostConstruct`注解,在构造方法之后执行,确保依赖注入已完成。同时提到了`InitializingBean`接口的`afterPropertiesSet()`方法作为备选,因为`@PostConstruct`在JDK9后可能被删除。

一,前言

有时候,我们可能需要在使用一个service或者工具之前,做一些数据的初始化或者对象的初始化。这里介绍一下在开发中常用的三种做法

 

二,实战

2.1  使用  static 关键字

这个方法是比较普遍的实现方式之一,了解过类加载顺序的朋友都知道,静态属性和静态方法都比实例属性和实例方法先加载,这里就不多介绍了。

 

2.2 实现 CommandLineRunner 接口

在springboot中,我们可以实现CommandLineRunner接口,重写run()方法。

当springboot程序启动的时候,会自动地执行run方法,我们可以在这个run方法里边进行一些系统数据的初始化,例如:加载字典,设置缓存等等。

具体代码:

@Component
@Slf4j
public class InitCommon implements CommandLineRunner {
    @Resource
    private DictAspect dictAspect;
    @Resource
    private BaseYmlProperties baseYmlProperties;

    @Override
    public void run(String... args) {
        log.info(">>>>>>>>>>>>>>> common init start <<<<<<<<<<<<<");
        dictAspect.initCache();
        UploadFileVO.setDomain(baseYmlProperties.getQiniuCdnProfile());
        log.info(">>>>>>>>>>>>>>> common init end <<<<<<<<<<<<<");
    }
}

当然,你还可以根据自己的业务需求,构建多个初始化工具。

如果有多个初始化工具,你可以使用@Order注解来指定他们的顺序,数值越小,优先级越高。

@Component
@Slf4j
@Order(1)
public class InitCommon implements CommandLineRunner {
    @Resource
    private DictAspect dictAspect;
    @Resource
    private BaseYmlProperties baseYmlProperties;

    @Override
    public void run(String... args) {
        log.info(">>>>>>>>>>>>>>> common init start <<<<<<<<<<<<<");
        dictAspect.initCache();
        UploadFileVO.setDomain(baseYmlProperties.getQiniuCdnProfile());
        log.info(">>>>>>>>>>>>>>> common init end <<<<<<<<<<<<<");
    }
}

@Order(2)
@Component
class Demo1 implements CommandLineRunner{

    @Override
    public void run(String... args) throws Exception {
        System.out.println("demo1 init...");
    }
}


@Order(3)
@Component
class Demo2 implements CommandLineRunner{

    @Override
    public void run(String... args) throws Exception {
        System.out.println("demo2 init...");
    }
}

 

2.3  使用@PostConstruct注解

@PostConstruct注解的方法,会在构造方法之后执行;

加载顺序为:Constructor > @Autowired > @PostConstruct > 静态方法;
特点:

  • 只有一个非静态方法能使用此注解
  • 被注解的方法不得有任何参数
  • 被注解的方法返回值必须为void
  • 被注解方法不得抛出已检查异常
  • 此方法只会被执行一次
@Component
@Slf4j
public class InitCommon implements CommandLineRunner {
    @Resource
    private DictAspect dictAspect;
    @Resource
    private BaseYmlProperties baseYmlProperties;


    @PostConstruct
    void init() {
        System.out.println(" @PostConstruct ...");
        System.out.println(dictAspect == null);
    }

    public InitCommon(){
        System.out.println(" Constructor... ");
        System.out.println(dictAspect == null);
    }


    @Override
    public void run(String... args) {
        log.info(">>>>>>>>>>>>>>> common init start <<<<<<<<<<<<<");
        dictAspect.initCache();
        UploadFileVO.setDomain(baseYmlProperties.getQiniuCdnProfile());
        log.info(">>>>>>>>>>>>>>> common init end <<<<<<<<<<<<<");
    }
}

可以看到,构造方法比@PostConstruct注解先直接,而且在构造方法执行的时候,注入的对象还是空的,当@PostConstruct注解执行的时候,注入的对象已经有值了。

 

 

2.4 实现InitializingBean接口,重写afterPropertiesSet()方法;

@Component
class TestInit implements InitializingBean {

    @Resource
    private DictAspect dictAspect;

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println(" afterPropertiesSet ...");
        System.out.println(dictAspect == null);
    }

    @PostConstruct
    void init() {
        System.out.println(" @PostConstruct ...");
        System.out.println(dictAspect == null);
    }

    public TestInit(){
        System.out.println(" Constructor... ");
        System.out.println(dictAspect == null);
    }
}

可以看到,也是和@PostConstruct注解差不多的结果。只不过,@PostConstruct注解已经在jdk9中计划被删除了,后续的话,还是用InitializingBean接口比较靠谱一点。

 

 

三,总结

总的来说,在springboot中初始化数据的方式还是挺多的,我们可以根据自己实际的场景来选用,而且有一些初始化的方式也是有先后顺序的,如果在初始化的时候依赖其他的注入bean,可能就要注意了。

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值