web-dev-qa-db-ja.com

Spring AOP-なぜaspectjweaverが必要ですか?

spring AOPで非常にシンプルなアスペクトを作成しました。それは機能しますが、実際に何が起こっているのかを理解するのに問題があります。なぜaspectjweaver.jarを追加する必要があるのか​​理解できませんか? Spring-AOPのドキュメントには、Spring-AOPを使用するだけであれば、aspectjコンパイラやウィーバーは必要ないと明記されています。

ただし、AOPランタイムはまだ純粋なSpring AOPであり、AspectJコンパイラーまたはウィーバーに依存していません。

私の構成は次のようになります。

<aop:aspectj-autoproxy />

@Aspect
@Service
public class RemoteInvocationAspect {

    @Before("execution(* at.test.mypackage.*.*(..))")
    public void test() {
        System.out.println("test");
    }
    ...

私もXML構成を試しましたが、何も変更しませんでした。たぶんそれを手放すことができたかもしれませんが、aspectj-weaverが使用される理由を本当に知りたいですか? Mavenに依存関係を追加しない場合、Java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException

35
Mario B

Spring AOP実装は、aspectj-weaverの一部のクラスを再利用していると思います。まだ動的プロキシを使用しています-バイトコードの変更は行いません。

次の春フォーラムの コメント が明確になるかもしれません。

この場合、SpringはAspectJウィーバーを使用していません。 aspectjweaver.jarのクラスの一部を単純に再利用しています。

-ラムニバス

31
gkamal

AspectJスタイルのポイントカット式を使用しています@Aspect@BeforeはAspectJの一部です。 このリンク を確認してください。

AspectJ-weaverに関しては、実際にはロード時にアスペクトをクラスに織り込むのバイトコードウィーバーです。

5
Santosh

私は最近、同様の質問がありました それがaspectjに依存しないのに、なぜspringはaspectjエラーを投げるのですか?

AspectJに依存せずにSpring AoPを使用するには、xmlで行う必要があります。注釈はAspectJの一部です。

また、本当にクールな表現言語はAspectJでのみサポートされています。したがって、明示的なポイントカットを定義する必要があります。セクション6.3.2を参照してください。ポイントカットの宣言: http://static.springsource.org/spring/docs/2.0.x/reference/aop.html section

このテクニックに関する詳細なドキュメントを見つけるのにまだ苦労しています。

4
beta-brad

あなたは春のウェブサイトを閲覧し、 docs.spring.io のページで答えを見つけることができます

@AspectJサポートは、XMLまたはJavaスタイル設定で有効にできます。いずれの場合も、AspectJのaspectjweaver.jarライブラリがアプリケーションのクラスパスにあることを確認する必要があります(バージョン1.6.8以降)。このライブラリは、AspectJディストリビューションの「lib」ディレクトリまたはMaven Centralリポジトリを介して利用できます。

0
Richard Xue

AspectJポイントカット式言語を使用する場合、aspectjtoolsまたはaspectjweaverの依存関係が必要です。

次のクラスをご覧ください。

Foo.Java

public interface Foo {
    void foo();
    void baz();
}

FooImpl.Java

public class FooImpl implements Foo {
    @Override
    public void foo() {
        System.out.println("Foo!");
    }

    @Override
    public void baz() {
        System.out.println("Baz!");
    }
}

MethodBeforeAdviceBarImpl.Java

import org.springframework.aop.MethodBeforeAdvice;
import Java.lang.reflect.Method;

public class MethodBeforeAdviceBarImpl implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("Bar!");
    }
}

App.Java version-1をご覧ください

import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.NameMatchMethodPointcutAdvisor;

public class App {

    public static void main(String[] args) {
        final MethodBeforeAdvice advice = new MethodBeforeAdviceBarImpl();

        final NameMatchMethodPointcutAdvisor nameMatchMethodPointcutAdvisor = new NameMatchMethodPointcutAdvisor();
        nameMatchMethodPointcutAdvisor.setMappedName("foo");
        nameMatchMethodPointcutAdvisor.setAdvice(advice);

        final ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.addAdvisor(nameMatchMethodPointcutAdvisor);

        final Foo foo = new FooImpl();
        proxyFactory.setTarget(foo);

        final Foo fooProxy = (Foo) proxyFactory.getProxy();
        fooProxy.foo();
        fooProxy.baz();
    }
}

この例を実行すると、出力は次のようになります。

Bar!
Foo!
Baz!

クラスパスにはorg.springframework:spring-context.jarのみが必要です。 NameMatchMethodPointcutAdvisorの代わりに、AspectJExpressionPointcutAdvisorを使用できます。

import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;
import org.springframework.aop.framework.ProxyFactory;

public class App {

    public static void main(String[] args) {
        final MethodBeforeAdvice advice = new MethodBeforeAdviceBarImpl();

        final AspectJExpressionPointcutAdvisor aspectJExpressionPointcutAdvisor = new AspectJExpressionPointcutAdvisor();
        aspectJExpressionPointcutAdvisor.setAdvice(advice);
        aspectJExpressionPointcutAdvisor.setExpression("execution(void biz.tugay.spashe.Foo.foo())");

        final ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.addAdvisor(aspectJExpressionPointcutAdvisor);

        final Foo foo = new FooImpl();
        proxyFactory.setTarget(foo);

        final Foo fooProxy = (Foo) proxyFactory.getProxy();
        fooProxy.foo();
        fooProxy.baz();
    }
}

繰り返しますが、クラスパスにspring-context.jarしかない場合、次のようになります。

An exception occured while executing the Java class. null: InvocationTargetException: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException

AspectJExpressionPointcutAdvisorクラスを調べると、AbstractGenericPointcutAdvisorを拡張し、AspectJExpressionPointcutのインスタンスに作業を委任していることがわかります。また、AspectJExpressionPointcutには次のインポートステートメントがあることがわかります。

import org.aspectj.weaver.patterns.NamePattern;
import org.aspectj.weaver.reflect.ReflectionWorld.ReflectionWorldException;
import org.aspectj.weaver.reflect.ShadowMatchImpl;
import org.aspectj.weaver.tools.ContextBasedMatcher;
import org.aspectj.weaver.tools.FuzzyBoolean;
import org.aspectj.weaver.tools.JoinPointMatch;
import org.aspectj.weaver.tools.MatchingContext;
import org.aspectj.weaver.tools.PointcutDesignatorHandler;
import org.aspectj.weaver.tools.PointcutExpression;
import org.aspectj.weaver.tools.PointcutParameter;
import org.aspectj.weaver.tools.PointcutParser;
import org.aspectj.weaver.tools.PointcutPrimitive;
import org.aspectj.weaver.tools.ShadowMatch;

AspectJExpressionPointcutが必要なクラスをロードできるように、実行時にクラスパスにaspectjtools依存関係が必要になります。

0
Koray Tugay