【问题标题】:What is the difference between Advisor and Aspect in AOP?AOP 中的 Advisor 和 Aspect 有什么区别?
【发布时间】:2014-08-02 06:24:17
【问题描述】:

我是 Spring AOP 的新手。根据我的理解,我注意到 Advisor(例如 DefaultPointcutAdvisor)和 Aspect(例如用 @Aspect 注释的类)都可以通过在调用方法时做更多的事情来帮助解决横切问题。

请问这两个词有什么区别?

【问题讨论】:

  • 旧问题使用了 Advice vs Aspect 比较,这是合法的,并且与 Advisor vs Aspect 比较不​​同:Advice - 指示在方法执行之前或之后要采取的操作。切入点 - 通过方法名称或正则表达式模式指示应拦截的方法。顾问 - 将“建议”和“切入点”组合成一个单元,并将其传递给代理工厂对象。

标签: java spring aop


【解决方案1】:

从 Spring 1.2 开始,Advisors 似乎是一种旧的“AOP lite”类型定义横切关注点,当时 Java 5 的使用仍然有些不常见,因此在 Spring 中没有使用 @AspectJ 语法(通过 Java 注释)。对于基于模式的 AOP 而不是基于注释的 AOP 或纯 AspectJ 语法的爱好者来说,这个概念仍然存在,请参阅Spring documentation on advisors

“顾问”的概念来自 Spring 中定义的 AOP 支持,在 AspectJ 中没有直接的等价物。顾问就像一个独立的小方面,有一个单个 条建议。通知本身由 bean 表示,并且必须实现 Spring 中的 Advice Types 中描述的通知接口之一。顾问可以利用 AspectJ 切入点表达式。

【讨论】:

  • 这应该是公认的答案,因为它清楚地回答了原始问题。
【解决方案2】:

大多数方面都是建议的组合,它定义了 方面的行为和一个切入点,它定义了方面应该在哪里执行。

Spring 认识到这一点并提供了顾问,这些顾问结合了建议和切入点 成一个对象。

更具体地说,PointcutAdvisor 执行此操作。

public interface PointcutAdvisor {
   Pointcut getPointcut();
   Advice getAdvice();
}

大部分 Spring 的内置切入点也有对应的PointcutAdvisor。 如果您想定义切入点及其管理的建议,这很方便 在一个地方。

阅读更多Spring in Action, 3rd Edition

截图

【讨论】:

  • 它们真的可以互相替代吗?
  • 我正在查看 Spring 的源代码和 PointcutAdvisor 接口我只看到 getPointcut() 方法而不是 getAdvice() ?
  • 我很生气这个答案被接受了,因为它没有解释为什么在 Spring 中同时存在顾问和方面,my answer 确实如此。关于顾问的说法(建议 + 切入点的组合)也适用于切面,只有切面更灵活,可以包含多个切入点和/或建议。
  • 如果有任何错误,请向《春天在行动》的作者提出您的关注。
【解决方案3】:

在我的理解中,Aspect 只是 Aspect Oriented Programming 行话,Advisor 是 Spring Framework 行话。

也许这个简单的例子会有所帮助:

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

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();
    }
}

App.java中运行ma​​in方法会输出:

Bar!
Foo!
Baz!

正如您在此处看到的,NameMatchMethodPointcutAdvisor 是一个 Advisor,它由一个 ma​​ppedName(即 切入点)和 Advice 本身组成,后者在这种情况下是 MethodBeforeAdvice

在面向方面的编程行话中,方面是建议 + 切入点,所以你去吧.. 顾问似乎毕竟是方面..

【讨论】:

  • 很好的解释
【解决方案4】:

Advice 是您对Pointcut 执行操作的方式。您可以使用之前、之后甚至周围的建议来应用您定义的任何操作。谈到 Spring Aspect,它只是一个高层次的类,它融合了两个概念:joinpointadvice。它可以通过基于 XML 的蓝图或以编程方式完成。此外,您应该指定要插入方面的点,它是通过使用 Joinpoint 来完成的。

Spring AspectsAdvice 也不能相互替代,因为 Aspects 只是连接点和建议的合并。


【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-04
    • 2010-10-02
    • 2011-12-12
    • 2010-09-16
    相关资源
    最近更新 更多