ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AnnotationTypeFilter(type));
Set<BeanDefinition> definitions = scanner.findCandidateComponents("com.java.xxx");
AbstractApplicationContext applicationContext = new AnnotationConfigApplicationContext(ApplicationContextConfig.class);
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
for (BeanDefinition beanDefinition : definitions) {
Map<String, Object> annotationAttributes = ((ScannedGenericBeanDefinition) beanDefinition).getMetadata().getAnnotationAttributes(type.getName());
if (annotationAttributes.containsKey("name")) {
String name = (String) annotationAttributes.get("name");
beanFactory.registerBeanDefinition(name, beanDefinition);
} else {
beanFactory.registerBeanDefinition(beanDefinition.getBeanClassName(), beanDefinition);
}
}
原理:通过scanner扫描自定义注解,生成bean definition;
根据注解的name,注入到beanFactory里;
完整代码:
public class TestCaseRunner {
protected ApplicationContext applicationContext;
protected Class type = TestClass.class;
public TestCaseRunner() {
init(type);
}
protected void init(Class type) {
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AnnotationTypeFilter(type));
Set<BeanDefinition> definitions = scanner.findCandidateComponents("com.java.xxx");
AbstractApplicationContext applicationContext = new AnnotationConfigApplicationContext(ApplicationContextConfig.class);
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
for (BeanDefinition beanDefinition : definitions) {
Map<String, Object> annotationAttributes = ((ScannedGenericBeanDefinition) beanDefinition).getMetadata().getAnnotationAttributes(type.getName());
if (annotationAttributes.containsKey("name")) {
String name = (String) annotationAttributes.get("name");
beanFactory.registerBeanDefinition(name, beanDefinition);
} else {
beanFactory.registerBeanDefinition(beanDefinition.getBeanClassName(), beanDefinition);
}
}
this.applicationContext = applicationContext;
}
public void run() {
Map<String, Object> testCaseMap = applicationContext.getBeansWithAnnotation(type);
for (Object testCaseObj : testCaseMap.entrySet()) {
Map.Entry testCaseEntry = (Map.Entry) testCaseObj;
String name = testCaseEntry.getKey().toString();
Object testCase = testCaseMap.get(name);
execute(name, testCase);
}
}
protected void execute(String name, Object testCase) {
Method beforeMethod = null, afterMethod = null;
List<Method> testMethods = new ArrayList<>();
Method[] methods = testCase.getClass().getMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(TestMethod.class)) {
testMethods.add(method);
} else if (method.isAnnotationPresent(BeforeTest.class)) {
beforeMethod = method;
} else if (method.isAnnotationPresent(AfterTest.class)) {
afterMethod = method;
}
}
for (Method method : testMethods) {
try {
Object instance = applicationContext.getBean(name);
if (beforeMethod != null) {
beforeMethod.invoke(instance);
}
method.invoke(instance);
if (afterMethod != null) {
afterMethod.invoke(instance);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestClass {
public String name() default "";
public String description () default "";
}
public class Main {
public static void main(String[] args) {
try {
TestCaseRunner testCaseRunner = new TestCaseRunner();
testCaseRunner.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@TestScript(name = "v1_test")
public class Version1Test {
@Autowired
@Qualifier("testScriptService")
private TestScriptService F;
@TestMethod
public void test() {
try {
Response response = F
.setUrl("xxx")
.sendRequest()
.getResponse();
boolean result = F.judgeNot(response.getContent(), null);
System.out.println("result : " + result);
} catch (Exception e) {
e.printStackTrace();
}
}
}