文档章节

spring context 扫描自定义注解并注入到application context

喔喔兒
 喔喔兒
发布于 2017/05/17 16:37
字数 339
阅读 324
收藏 1
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();
        }
    }
}

 

© 著作权归作者所有

喔喔兒
粉丝 26
博文 64
码字总数 11003
作品 0
大连
程序员
私信 提问
Quartz与Spring的整合-Quartz中的job如何自动注入spring容器托管的对象

问题 Quartz中的job是由Quartz框架动态创建的(配置该job的classname,通过反射创建),而job一般会依赖到配置在spring中的bean,怎样获取或者更好的自动注入这些依赖bean呢? 预期效果 我们...

天外飞鱼
2014/07/13
763
0
浅谈application-*.xml和springmvc-.xml的区别

项目配置说明 一般springMVC和Spring的整合过程中,我们喜欢配置两个文件application-*.xml和springmvc-.xml,但是配置不好的话,很容易出现这样的问题:Injection of resource dependencie...

小车车
2016/07/07
77
0
Spring使用ComponentScan扫描Maven多模块工程的其它模块

说明:在新建好了Maven多模块工程后,如果想要在其它模块也能使用Spring的对象管理,比如@Autowrited这些注入方式,那么就必须开启包扫描的功能才能使其进行注入到Spring的对象管理中。 解决...

easonjim
2018/01/20
0
0
Spring学习笔记1——基础知识

1.在java开发领域,Spring相对于EJB来说是一种轻量级的,非侵入性的Java开发框架,曾经有两本很畅销的书《Expert one-on-one J2EE Design and Development》和《Expert one-on-one J2EE deve...

李长春
2011/10/09
516
0
Spring注解@Component、@Repository、@Service、@Controll

很长时间没做web项目都把以前学的那点框架知识忘光了,今天把以前做的一个项目翻出来看一下发现用·@Component标记一个组件,而网上有的用@Service标记组件,我晕就查了一下资料: Spring 2...

沉默的子明
2014/05/14
63
0

没有更多内容

加载失败,请刷新页面

加载更多

编程作业20190210900169

1编写一个程序,提示用户输入名和姓,然后以“名,姓”的格式打印出来。 #include <stdio.h>#include <stdlib.h> int main(){ char firstName[20]; char lastName[20]; print......

1李嘉焘1
19分钟前
4
0
补码的优点及原理分析

只讨论整数 1.计算机内部为什么没有减法器? 减法运算本身其实就是加法,如x - y即x +(-y),所以只需要将负数成功表示出来并可以参加加法运算,那加法器就可同时实现“+”和“-”的运算。这...

清自以敬
35分钟前
63
0
Docker 可视化管理 portainer

官网安装指南: https://portainer.readthedocs.io/en/latest/deployment.html docker-compose.yml 位置,下载地址:https://downloads.portainer.io/docker-compose.yml...

Moks角木
今天
5
0
Spring Security 实战干货:必须掌握的一些内置 Filter

1. 前言 上一文我们使用 Spring Security 实现了各种登录聚合的场面。其中我们是通过在 UsernamePasswordAuthenticationFilter 之前一个自定义的过滤器实现的。我怎么知道自定义过滤器要加在...

码农小胖哥
今天
8
0
常见分布式事务解决方案

1 微服务的发展 微服务倡导将复杂的单体应用拆分为若干个功能简单、松耦合的服务,这样可以降低开发难度、增强扩展性、便于敏捷开发。当前被越来越多的开发者推崇,很多互联网行业巨头、开源...

asdf08442a
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部