AspectJを使ってAnnotationを活用しよう 補足編

本編はこちら。

補足編として、SpringAOPを使ったAnnotationの取得方法について。

本編では、AspectJアノテーションを使ったInterceptorを作って、その中でアノテーションを取得する方法を紹介しました。この補足編では、SpringAOPを使ったInterceptorを作って、同じようにアノテーションを取得する方法を紹介します。

まずはInterceptorを作りましょう。下記のコードを参考に、Interceptorクラスを作ってください。

public class SampleAopInterceptor implements MethodInterceptor {

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation
     * )
     */
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        SampleAnnotation annotation = invocation.getMethod().getAnnotation(SampleAnnotation.class);
        String arg = invocation.getArguments()[0].toString();
        String s =
                String.format("%s - spring aop logging. annotation is %s.", arg, annotation.value());
        Object[] args = { s };

        return invocation.getMethod().invoke(invocation.getThis(), args);
    }

}

上記のコードでは、まず呼び出されたメソッドに付与されているSampleAnnotationを取得しています。そして、メソッドの引数を取得して内容を編集し、最後に編集した引数を渡して本来のメソッドを呼び出しています。

次に、Interceptorの対象となるメソッドを定義しましょう。下記のコードを参考にLogicクラスを作成してください。

@Service
public class SampleLogic2 {

    @SampleAnnotation(SampleEnum.SAMPLE1)
    public void sample(String s) {
        System.out.println("arg=" + s);
    }

}

最後にSpringのBean定義ファイルで、AOPのPointcutやAdviceの設定を行い、それをSampleAopInterceptorクラスに適用します。下記の設定をBean定義ファイルに記述してください。

<bean id="sampleAopInterceptor" class="jp.example.test.sample.SampleAopInterceptor" />
    
<aop:config>
    <aop:pointcut expression="bean(*Logic2)" id="aopPointcut"/>
    <aop:advisor advice-ref="sampleAopInterceptor" pointcut-ref="aopPointcut"/>
</aop:config>

では、正しく動作するかどうか、テストを実行して確認してみましょう。下記のコードを、前回の記事で作成したテストクラスに追加して、実行してみてください。SampleLogic2のBeanを使うことをお忘れなく!

@Test
public void testSample02() {
    sampleLogic2.sample("test for spring aop");
}

で実行してみると・・・

12:25:28.506 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
12:25:28.506 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
ココ!=>arg=test for spring aop - spring aop logging. annotation is SAMPLE1.
12:25:28.513 [main] DEBUG o.s.t.c.s.DirtiesContextTestExecutionListener - After test method: context [[TestContext@5d61dfb5 testClass = SampleLogicTest, locations = array<String>['classpath:spring-beans.xml'], testInstance = jp.example.test.sample.SampleLogicTest@44a613f8, testMethod = testSample02@SampleLogicTest, testException = [null]]], class dirties context [false], class mode [null], method dirties context [false].
12:25:28.513 [main] DEBUG o.s.t.c.s.DirtiesContextTestExecutionListener - After test class: context [[TestContext@5d61dfb5 testClass = SampleLogicTest, locations = array<String>['classpath:spring-beans.xml'], testInstance = [null], testMethod = [null], testException = [null]]], dirtiesContext [false].

想定通りの出力がされてますね!

いかがでしたか?今後は、他のAOPについてもここで紹介していこうと思います。