二.一.二 实现 CommandLineRunner 的 run 方法
package top.yueshushu.init.line; import org.springframework.boot.CommandLineRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.util.Base64Utils; import org.springframework.util.StringUtils; import top.yueshushu.init.util.HardwareUtil; @Component @Order(1) public class InitCommandLineRunner implements CommandLineRunner { @Override public void run(String... args) { //args 获取传入的参数。 //容器启动时,进行的操作。 如获取计算机的 机器码 String cpuId = HardwareUtil.getCpuId(); if(!StringUtils.hasText(cpuId)){ System.out.println(">>>没有机器码"); } String singleSignature = Base64Utils.encodeToString(cpuId.getBytes()); System.out.println(">>>机器码是:"+singleSignature); } }
@Order(1) 表示顺序。 可以定义多个启动方法, 数据越小,越先启动。
参数 String … args 对应的就是 main 方法里面的参数,获取参数的方式也是相同的.
二.一.三 测试
是在服务启动之后,进行处理的. 这个时候,已经是拥有 @Component, @Controller,@Service,@Repository 相关的实例了
二.一.四 使用组件
@Component @Order(2) public class InitCommandLineRunner2 implements CommandLineRunner { @Autowired private UserService userService; @Override public void run(String... args) { userService.set(); userService.get(); } }
启动服务
二.二 ApplicationRunner
将 InitCommandLineRunner 和 InitCommandLineRunner2 去掉 @Order 和 @Component 注解
二.二.一 实现 ApplicationRunner 的 run 接口
@Component @Order(3) public class InitApplicationRunner implements ApplicationRunner { @Autowired private UserService userService; @Override public void run(ApplicationArguments args) throws Exception { //在运行时,进行的操作. Random random=new Random(); System.out.println(">>>输出值:"+random.nextInt(100)); userService.set(); userService.get(); } }
参数使用的是 ApplicationArguments args
- args.getNonOptionArgs();`可以用来获取命令行中的无key参数(和CommandLineRunner一样)
- args.getOptionNames();`可以用来获取所有key/value形式的参数的key
- args.getOptionValues(key);可以根据key获取key/value 形式的参数的value
- args.getSourceArgs();则表示获取命令行中的所有参数
二.二.二 测试
二.三 @PostConstruct 注解
@PostConstruct 注解,用于在依赖关系注入完成之后,需要执行的方法,用于执行初始化,只执行一次。
也就是说, 是在 @Autowired/@Resource 之后执行的注解
二.三.一 不需要继承接口
@Component @Order(4) public class InitMethod { @Autowired private UserService userService; @PostConstruct public void initName(){ System.out.println(">>>>初始化名称模块"); } @PostConstruct public void initSet(){ userService.set(); } @PostConstruct public void initGet(){ userService.get(); } }
二.三.二 测试
在 ExecutorService 服务之前执行的。
与 init() 方法相同.
二.三.三 定义静态类
在实际项目中,一个相对完整的业务链,会有很多个 相关的 Service 。
通常会将相应的几个 Service进行封装,封装成一个工具类,对外提供方法.
先将 InitMethod 类上的 @Component 注解去掉
二.三.三.一 不使用 @PostConstructor 注解
定义工具类
@Component public class MyUserServiceUtil { @Autowired private UserService userService; public void handler(){ //先设置值 userService.set(); //再获取值 userService.get(); } }
使用工具类
先注入,再使用
@SpringBootTest public class PostTest { //先注入 @Autowired private MyUserServiceUtil myUserServiceUtil; @Test public void test(){ System.out.println(">>>先注入,再使用"); //再使用 myUserServiceUtil.handler(); } }
每次都需要先注入,再使用。
如果能够定义成相关的静态方法,就好了.
二.三.三.二 使用 @PostConstructor 注解处理成静态类
@Component public class MyUserServiceUtil2 { //执行的顺序,先 Component, 再Autowired,后 PostConstruct //内部注入 @Autowired private UserService userService; //定义代理的静态属性 private static UserService userServiceImpl; @PostConstruct public void setComponent(){ //赋予属性值 userServiceImpl=userService; } //方法是静态的,那么 调用者必须是静态的. public static void handler(){ //先设置值 userServiceImpl.set(); //再获取值 userServiceImpl.get(); } }
在使用时,直接用静态方法的形式即可.
@SpringBootTest public class PostTest { //先注入 @Autowired private MyUserServiceUtil myUserServiceUtil; @Test public void test(){ System.out.println(">>>先注入,再使用"); //再使用 myUserServiceUtil.handler(); } @Test public void test2(){ System.out.println("静态方法,直接使用"); MyUserServiceUtil2.handler(); } }
运行 test2() 方法
这种形式,在开发中很常用,一定要记住.
这就是SpringBoot 系统启动任务的常用方法.