在开发中可能会有这样的情景。需要在容器启动的时候执行一些内容。比如读取配置文件,数据库连接之类的。SpringBoot给我们提供了两个接口来帮助我们实现这种需求。这两个接口分别为CommandLineRunner和ApplicationRunner。他们的执行时机为容器启动完成的时候。
这两个接口中有一个run方法,我们只需要实现这个方法即可。这两个接口的不同之处在于:ApplicationRunner中run方法的参数为ApplicationArguments,而CommandLineRunner接口中run方法的参数为String数组。目前我在项目中用的是ApplicationRunner。是这么实现的:
先自定义注解 package com..dm.driver.dao.test;
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface TestClass { }
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface TestMethod { }
package com..dm.driver.dao.test;
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.context.support.ApplicationObjectSupport; import org.springframework.stereotype.Component; import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Method; import java.util.Map;
@Component public class DriverTest extends ApplicationObjectSupport implements ApplicationRunner { private Logger logger = LoggerFactory.getLogger(getClass());
int testCount; int succCount; @Override public void run(ApplicationArguments args) throws Exception { if(args.containsOption("test")) { //启动时添加test为参数,待服务启动完成之后开始调用 logger.info("执行测试"); doTest(args); System.exit(0); } }
private void doTest(ApplicationArguments args) { testCount = 0; succCount = 0; //扫描所有带有TestClass的注解类 Map<String ,Object> beans = getApplicationContext().getBeansWithAnnotation(TestClass.class); for(Object bean : beans.values()) { logger.info("测试类{}", bean.getClass().getName()); ReflectionUtils.doWithMethods(bean.getClass(), m->testMethod(bean, m), m->m.isAnnotationPresent(TestMethod.class)); } logger.info("testcount={} succcount={}", testCount, succCount); }
private void testMethod( Object bean, Method m) { try { logger.info("测试方法{}", m.getName()); testCount++; Object ret = ReflectionUtils.invokeMethod(m, bean); if(ret == null || ret instanceof Boolean && ((Boolean)ret)) { succCount++; } }catch(Throwable t) { logger.error("测试失败", t); } } }
@Component @Lazy @TestClass //定义测试类 public class ClieckTest extends AbstractTest{ @Autowired DmDriverService driverService; @TestMethod //定义测试方法 public boolean testPay1() { RequestParameter parameter = new RequestParameter(); List<Response> response = driverService.getResult(request); System.out.println(JSON.toJSONString(response)); return response != null && response.size() > 0;
}
@TestMethod //定义测试方法 public boolean testPlay2() { RequestParameter parameter = new RequestParameter(); parameter.setAppversion("5.4.0"); List<Response> response = driverService.getResult(request); System.out.println(JSON.toJSONString(response)); response = driverService.getNativeResult(nativeRequest); System.out.println(JSON.toJSONString(response)); return response != null && response.size() > 0; } }
