阅读 70

SpringBoot中启动加载类(springboot启动加载外部配置文件)

项目开发中,经常会碰到需要在项目启动后自动执行一些方法,如缓存的预热等功能,在SpringBoot中就提供了方法来完成这种功能需求。

1. ApplicationRunner

1.1 ApplicationRunner的定义

ApplicationRunner是org.springframework.boot包中定义的接口,在使用时需要定义类实现ApplicationRunner接口,并实现接口中的run()方法。

SpringBoot中对ApplicationRunner接口的定义源码为:

@FunctionalInterface public interface ApplicationRunner {     void run(ApplicationArguments args) throws Exception; } 复制代码

1.2 定义类实现ApplicationRunner

类实现ApplicationRunner接口时,需要将类注入到容器中,否则SpringBoot无法获取到定义类的对象并自动执行其中的run()方法。

 @Component  public class AutoRunApplicationRunner implements ApplicationRunner {      private static final Logger log = LoggerFactory.getLogger(AutoRunApplicationRunner.class);        @Override      public void run(ApplicationArguments args) throws Exception {          log.info("实现ApplicationRunner的run方法自动执行,时间:{}", new Date());      }  } 复制代码

1.3 项目执行结果

定义类实现ApplicationRunner接口,重写其中的run方法后,启动项目,可以看到如下效果,表示方法在项目启动后自动执行,并执行方法中内容。 image.png

2. CommandLineRunner

2.1 CommandLineRunner接口定义

CommandLineRunner同样是org.springframework.boot包中定义的接口,在使用时需要定义类实现ApplicationRunner接口,并实现接口中的run()方法。

其中,CommandLineRunner接口的定义为:

 @FunctionalInterface  public interface CommandLineRunner {      void run(String... args) throws Exception;  } 复制代码

与ApplicationRunner接口不同的是,CommandLineRunner接口接受的参数类型不同,可以传入多个参数。

2.2 定义实现类

定义类实现CommandLineRunner接口后,同样也需要将类注入到容器中,否则SpringBoot无法自动执行run()方法。

 @Component  public class AutoRunCommandLineRunner implements CommandLineRunner {      private static final Logger log = LoggerFactory.getLogger(AutoRunCommandLineRunner.class);      @Override      public void run(String... args) throws Exception {          log.info("实现AutoRunCommandLineRunner的run方法自动执行,时间:{},参数内容:", new Date(),args);      }  } 复制代码

2.3 执行结果

实现CommandLineRunner接口的类在项目启动后输出结果如下图:

image.png

3. ApplicationRunner和CommandLineRunner

3.1 两者的区别

如果项目中同时实现了ApplicationRunner和CommandLineRunner两个接口,则在项目启动后会有:

  1. 会先执行ApplicationRunner实现类中run()方法,后执行CommandLineRunner实现类中run()方法;

  2. ApplicationRunner实现类的run()方法执行完之前,不会执行CommandLineRunner实现类的run()方法。

尽管两个接口十分相似,且都需要重写有参的run()方法,但不同的是ApplicationRunner接口的run()方法参数类型是ApplicationArguments对象,而CommandLineRunner中run()方法的参数类型是String。

如图所示为在启动程序时传入了参数信息,则参数会相应的传入到两个接口对应实现类的run()方法中。

image.png

可以得到执行的结果信息:

image.png

3.2 @Order定义执行顺序

对于ApplicationRunner和CommandLineRunner的执行顺序并不是绝对的,除了默认的执行顺序外。还可以使用@Order注解来指定两种实现类的执行顺序。

@Order注解是spring框架中的org.springframework.core.annotation包提供的注解,详细信息:

 @Retention(RetentionPolicy.RUNTIME)  @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})  @Documented  public @interface Order {      int value() default 2147483647;  } 复制代码

由于默认的执行顺序是ApplicationRunner实现类的run()方法早于CommandLineRunner实现类的run()方法, 因此使用注解为CommandLineRunner的实现类标注@Order(value = 1),为ApplicationRunner的实现类使用注解@Order(value = 2),则可以得到与默认顺序相反的的执行顺序结果。

image.png

4. @PostContstruct

@PostContstruct注解是Java本身的javax.annotation包中提供的注解内容,用来修饰一个非静态的方法,并在类创建完成后执行被标注的方法。

在Spring中框架中,标注该注解的方法执行顺序在构造方法和属性注入之后,即类加载完成后执行。

4.1 注解定义

根据@PostContstruct注解的相关定义,可以看到该注解只可以标注于方法之上。

@Documented @Retention (RUNTIME) @Target(METHOD) public @interface PostConstruct { } 复制代码

4.2 @PostContstruct注解的使用

实际使用@PostContstruct注解时,需要定义一个非静态方法,并为方法使用注解,表示该方法会在当前类初始化完成后自动执行。

使用时需要注意: 因为注解是在类对象构造完成后执行,因此不可以标注在类的静态方法上

@Component public class AutoRunUserAnnotation {     private static final Logger log = LoggerFactory.getLogger(AutoRunUserAnnotation.class);     @PostConstruct     public void init(){         log.info("方法使用@PostConstruct注解来自动执行,时间:{}", new Date());     } } 复制代码

在项目开发时,如果定义的类使用了容器类注解,Spring会在容器初识化时加载所有使用相关注解的类对象,在容器加载完毕后,完成bean对象的创建,会立即执行类对象中使用@PostContstruct标注的方法。

执行结果:(在容器加在完成后执行,在项目最终启动之前)

image.png


作者:showsen
链接:https://juejin.cn/post/7028963158693773348


文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐