3

内部でSpring 2.5を使用するServiceMix 3.2で実行されているアプリの実行を追跡しようとしています。私は CGLIB (インターフェイスではなくクラスをアドバイスする) を使用しており、ポイントカットを使用してトレースを指示したいと考えています。したがって、次のように、サービス ユニットの xbean.xml ファイルの 1 つでロード時のウィービングを実行するように Spring を構成しました。

<bean id="debugInterceptor"
    class="org.springframework.aop.interceptor.SimpleTraceInterceptor"/>
<aop:config proxy-target-class="true">
    <aop:advisor advice-ref="debugInterceptor"
        pointcut="within(my.package.AClass)" order="1"/>
</aop:config>

my.package.AClassクラスはアドバイスを受けますが、ポイントカットで指定したものに限定されません。つまり、アドバイスを受ける以外のクラスのメソッドは、ここでは重要ではありませんが、クラスのロードを中断します。

このようにポイントカットを定義しようとしましたが、違いはありませんでした:

<aop:advisor advice-ref="debugInterceptor"
    pointcut="execution(* my.package.AClass.*(..))" order="1"/>

my.package..*一般的には以外のクラスにアドバイスしたいのmy.package.no_aop.*ですが、なかなか進んでいないようです。

CGLIB が 以外のクラスを処理するのはなぜmy.package.AClassですか? どうすれば防ぐことができますか?( AspectJとは対照的に) Spring AOPに切り替えると違いはありますか?

4

1 に答える 1

1

私は Spring 3.0.x と @AspectJ アノテーションを使用してそれを行いましたが、2.5 と XML を使用しても類似しているはずです。

my.pkgアドバイスが必要なパッケージのクラスA :

package my.pkg;

public class ClassA {

    public void doFromClassA() {
        System.out.println("Hello from A!");
    }
}

my.pkg.noaopアドバイスする必要のないパッケージのクラス B :

package my.pkg.noaop;

public class ClassB {

    public void doFromClassB() {
        System.out.println("Hello from B!");
    }
}

アスペクト:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class AopTestAspect {

    @Around("within(my.pkg..*) && !within(my.pkg.noaop..*)")
    public void advice(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("Hello from adviced!");
        pjp.proceed();
    }
}

構成 (XML バージョンが必要な場合はお知らせください):

import my.pkg.ClassA;
import my.pkg.noaop.ClassB;

import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AopTestConfig {

    @Bean
    public ClassA classA() {
        return new ClassA();
    }

    @Bean
    public ClassB classB() {
        return new ClassB();
    }

    @Bean
    public AopTestAspect aspect() {
        return new AopTestAspect();
    }

    @Bean
    public AnnotationAwareAspectJAutoProxyCreator autoProxyCreator() {
        AnnotationAwareAspectJAutoProxyCreator autoProxyCreator = new AnnotationAwareAspectJAutoProxyCreator();
        autoProxyCreator.setProxyTargetClass(true);
        return autoProxyCreator;
    }
}

テスト:

import my.pkg.ClassA;
import my.pkg.noaop.ClassB;

import org.junit.Test;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class AopTest {

    @Test
    public void test() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(AopTestConfig.class);
        applicationContext.refresh();

        ClassA a = BeanFactoryUtils.beanOfType(applicationContext, ClassA.class);
        ClassB b = BeanFactoryUtils.beanOfType(applicationContext, ClassB.class);

        a.doFromClassA();
        b.doFromClassB();
    }
}

そして、テストからの出力:

Hello from adviced!
Hello from A!
Hello from B!

ご覧のとおり、ClassAアドバイスを受けただけです。

結論

重要なのはポイントカットの表現です:

within(my.pkg..*) && !within(my.pkg.noaop..*)

于 2011-07-15T10:35:11.987 に答える