在开发中可能会有这样的情景。需要在容器启动的时候执行一些内容。比如读取配置文件,数据库连接之类的。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());
//遍历bean的所有method,m为里面的Method,m.isAnnotationPresent为判断method上面是否有TestMethod注解做为条件,bean.getClass()为对应的class
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++;
//执行 bean中的m方法method
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;
}
}