java - 从 Spring 上下文访问 Spring 测试类对象

标签 java spring reflection annotations

奇怪的主题继续问题本身:)有没有办法从 Spring 应用程序上下文到达 Spring 测试类?问题详细信息作为注释 block 隐藏在“SimpleDaoHandler”类中:)

测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/applicationContext-core.xml")
public class DbFuntionTests {

    @TestAnnotation
    private UserSessionDao userSessionDao; 

    @Test
    public void testOracleTimestamp() throws Exception {
        userSessionDao.findAll();
    }
}

Spring上下文初始化后的处理程序类:

@Component
public class SimpleDaoHandler implements ApplicationContextAware, InitializingBean {
    private ApplicationContext applicationContext;
    private static Logger logger = Logger.getLogger(SimpleDaoHandler.class);

    @Override
    public void afterPropertiesSet() throws Exception {
        //I have the application context now, via method "setApplicationContext"
        // and need to get test class object to get the
        // annotated field "TestAnnotation" because I also need to set this
        // field with my business logic, using reflection.
        // Problem is; test class object is not included in the
        // "applicationContext" as a bean and I don't know how to access my 
        //test class which is already starting the spring context initialization. 
        //I need to get that test class object.
    }

    @Override
    public void setApplicationContext(final ApplicationContext applicationContext)
            throws BeansException {
        this.applicationContext = applicationContext;
    }

有什么线索吗?

最佳答案

也许创建一些 post processor 会更好使用您的 @TestAnnotation ?您可以看一下 Spring AutowiredAnnotationBeanPostProcessor,它扫描具有 @Autowire 注解的字段/方法的 bean 并处理它们。我认为这是您尝试实现的目标,并且 bean 后处理器是解决此类问题的最干净的解决方案(由 Spring 本身使用)。

请查看下面的示例 - MyAnnotationPostProcessor 扫描应用程序上下文中每个 bean 上的 MyAnnotation 并记录适用的字段。 (当然,除了记录之外,您还可以采取一些行动;))。请注意,您的注释必须声明 RetentionPolicy.RUNTIME;否则,它在运行时将不可见。

public final class MyAnnotationPostProcessor implements BeanPostProcessor {

    private static final Log LOG = LogFactory.getLog(MyAnnotationPostProcessor.class);

    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        final Set<Field> annotatedFields = getAnnotatedFields(bean.getClass());
        for (Field annotatedField : annotatedFields) {
            LOG.info("Post process before initialization " + beanName + "," + annotatedField);
        }
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        final Set<Field> annotatedFields = getAnnotatedFields(bean.getClass());
        for (Field annotatedField : annotatedFields) {
            LOG.info("Post process after initialization " + beanName + "," + annotatedField);
        }
        return bean;
    }

    private Set<Field> getAnnotatedFields(final Class<?> clazz) {
        final Set<Field> annotatedFields = new HashSet<Field>();
        for (Field field : clazz.getDeclaredFields()) {
            if(hasMyAnnotation(field)) {
                annotatedFields.add(field);
            }
        }
        return annotatedFields;
    }

    private boolean hasMyAnnotation(final AccessibleObject ao) {
        return AnnotationUtils.getAnnotation(ao, MyAnnotation.class) != null;
    }
}

测试类和注释:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=AnnotationConfigContextLoader.class)
public class MySpringTest {

    @MyAnnotation
    private UserSessionDAO dao;

    @Configuration
    static class TestContext {
        @Bean
        public static MyAnnotationPostProcessor myAnnotationPostProcessor() {
            return new MyAnnotationPostProcessor();
        }
    }

    @Test
    public void test() {

    }
}

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

}

关于java - 从 Spring 上下文访问 Spring 测试类对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16694323/

相关文章:

java - 如何通过 Java 中的通用通配符捕获创建数组的克隆?

java - setLong 方法参数与数据类型不匹配

java - Spring Boot 文件上传 - 连接由对等错误重置

java - 查看对象是否是通过字符串传递的类的实例

java - Hibernate 找不到 persistence.xml 文件

java - 在下面的代码片段中使用 set 方法的目的

自定义Apache Camel数据格式的Spring配置

mysql - 如何在我的 web 应用程序中模拟垃圾概念?

java - 在运行时绑定(bind)到正确的构造函数 - Java

c# - 在 ORM 中将 lambda 表达式转换为 SQL?