奇怪的主题继续问题本身:)有没有办法从 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/