Spring AOP的 - 为什么我需要aspectjweaver?(Spring AOP - wh

2019-06-26 05:38发布

我写了Spring AOP的一个非常简单的看点。 它的工作原理,但我有一些问题了解什么是真正回事。 我不明白为什么我要补充的aspectjweaver.jar? 弹簧AOP文档中明确指出,我不需要AspectJ编译器或编织器,只要我只是用Spring的AOP:

,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织入使用? 如果我不加在行家依赖我得到java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException

Answer 1:

Spring AOP的实现,我认为是重用从AspectJ的织入一些类。 它仍然使用动态代理 - 不执行字节码的修改。

下面的评论从春季论坛会澄清。

春天不使用在这种情况下AspectJ织入。 这只不过是重复使用一些类从aspectjweaver.jar。

-Ramnivas



Answer 2:

您正在使用的AspectJ风格的切入点表达@Aspect@Before是AspectJ的一部分。 检查此链接 。

关于AspectJ-weaver ,其实际上是一个字节码织入其在加载时间编织方面为类



Answer 3:

我最近有一个类似的问题, 为什么春天抛出AspectJ的错误,如果它不依赖于AspectJ的?

要使用Spring AOP中没有AspectJ的依赖,必须在XML来完成。 注解是AspectJ中的一部分。

此外,非常酷的表达式语言只由AspectJ的支持。 所以,你必须定义明确的点式切口。 请参见6.3.2节。 声明一个切入点: http://static.springsource.org/spring/docs/2.0.x/reference/aop.html节

我仍然无法找到这种技术的任何复杂的文档。



Answer 4:

您可以浏览春的网站,找到的网页上的答复docs.spring.io

@AspectJ支持后可以用XML或Java风格配置中启用。 在这两种情况下,你还需要确保AspectJ的aspectjweaver.jar库是您的应用程序(1.6.8或更高版本)的类路径。 这个库可以在AspectJ的分布“lib”目录下或通过Maven的中央仓库可用。



Answer 5:

当您使用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:弹簧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();
    }
}

再次,如果我只有在我的类路径弹簧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语句:

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;

您需要在运行时类路径中aspectjtools依赖性,因此AspectJExpressionPointcut可以加载它需要的类。



文章来源: Spring AOP - why do i need aspectjweaver?