37

私はSpringAOPで非常に単純なアスペクトを作成しました。それは機能しますが、実際に何が起こっているのかを理解するのにいくつか問題があります。なぜ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

4

5 に答える 5

33

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

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

この場合、SpringはAspectJウィーバーを使用していません。それは単にaspectjweaver.jarのクラスのいくつかを再利用しているだけです。

-ラムニバス

于 2012-07-12T07:51:05.853 に答える
6

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

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

于 2012-07-12T07:42:53.670 に答える
4

私は最近同様の質問をしました。それがaspectjに依存しないのに、なぜ春はaspectjエラーをスローするのですか?

AspectJ依存関係なしでSpringAoPを使用するには、xmlで実行する必要があります。注釈はAspectJの一部です。

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

この手法に関する詳細なドキュメントを見つけるのにまだ問題があります。

于 2013-05-20T16:07:54.567 に答える
2

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バージョン-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依存関係が必要になります。

于 2017-11-01T20:00:14.860 に答える
0

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

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

于 2015-07-07T01:49:27.250 に答える