2

奇妙な主題は質問自体を続けます:)春のアプリケーションコンテキストから春のテストクラスに到達する方法はありますか? 質問の詳細は、コメント ブロックとして「SimpleDaoHandler」クラスに隠されています :)

テスト クラス:

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

    @TestAnnotation
    private UserSessionDao userSessionDao; 

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

スプリング コンテキストの初期化後のハンドラー クラス:

@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;
    }

どんな手掛かり?

4

2 に答える 2

2

たぶん、あなた@TestAnnotation? AutowiredAnnotationBeanPostProcessorアノテーションが付けられたフィールド/メソッドを持つ Bean をスキャンして処理するSpring を見ることができ@Autowireます。それはあなたが達成しようとしているものだと思います.Beanポストプロセッサは、そのような問題に対する最もクリーンな解決策です(Spring自体によって使用されます)。

以下の例を見てください。アプリケーション コンテキスト内の各 BeanのMyAnnotationPostProcessorスキャンと、該当するフィールドのログです。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 {

}
于 2013-05-22T15:18:19.907 に答える