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方法后,启动项目,可以看到如下效果,表示方法在项目启动后自动执行,并执行方法中内容。
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接口的类在项目启动后输出结果如下图:
3. ApplicationRunner和CommandLineRunner
3.1 两者的区别
如果项目中同时实现了ApplicationRunner和CommandLineRunner两个接口,则在项目启动后会有:
会先执行ApplicationRunner实现类中run()方法,后执行CommandLineRunner实现类中run()方法;
ApplicationRunner实现类的run()方法执行完之前,不会执行CommandLineRunner实现类的run()方法。
尽管两个接口十分相似,且都需要重写有参的run()方法,但不同的是ApplicationRunner接口的run()方法参数类型是ApplicationArguments对象,而CommandLineRunner中run()方法的参数类型是String。
如图所示为在启动程序时传入了参数信息,则参数会相应的传入到两个接口对应实现类的run()方法中。
可以得到执行的结果信息:
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),则可以得到与默认顺序相反的的执行顺序结果。
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标注的方法。
执行结果:(在容器加在完成后执行,在项目最终启动之前)
作者:showsen
链接:https://juejin.cn/post/7028963158693773348