无论您如何创建 AOP 代理,您都可以使用界面来操作它们。任何 AOP 代理都可以强制转换为此 接口,无论它实现哪些其他接口。此接口包括 方法如下:org.springframework.aop.framework.Advised

  • Java

  • Kotlin

Advisor[] getAdvisors();

void addAdvice(Advice advice) throws AopConfigException;

void addAdvice(int pos, Advice advice) throws AopConfigException;

void addAdvisor(Advisor advisor) throws AopConfigException;

void addAdvisor(int pos, Advisor advisor) throws AopConfigException;

int indexOf(Advisor advisor);

boolean removeAdvisor(Advisor advisor) throws AopConfigException;

void removeAdvisor(int index) throws AopConfigException;

boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException;

boolean isFrozen();
fun getAdvisors(): Array<Advisor>

@Throws(AopConfigException::class)
fun addAdvice(advice: Advice)

@Throws(AopConfigException::class)
fun addAdvice(pos: Int, advice: Advice)

@Throws(AopConfigException::class)
fun addAdvisor(advisor: Advisor)

@Throws(AopConfigException::class)
fun addAdvisor(pos: Int, advisor: Advisor)

fun indexOf(advisor: Advisor): Int

@Throws(AopConfigException::class)
fun removeAdvisor(advisor: Advisor): Boolean

@Throws(AopConfigException::class)
fun removeAdvisor(index: Int)

@Throws(AopConfigException::class)
fun replaceAdvisor(a: Advisor, b: Advisor): Boolean

fun isFrozen(): Boolean

该方法为每个顾问、拦截器或 已添加到工厂的其他建议类型。如果添加了 , 此索引处返回的顾问是您添加的对象。如果您添加了 拦截器或其他建议类型,Spring 将其包装在顾问中,带有 总是返回的 pointcut。因此,如果您添加了 ,则顾问 为此索引返回的是返回 your 的 pointcut 和匹配所有类和方法的 pointcut。getAdvisors()AdvisorAdvisortrueMethodInterceptorDefaultPointcutAdvisorMethodInterceptor

这些方法可用于添加任何 .通常,顾问持有 Pointcut 和 advice 是通用的,您可以将其与 任何建议或要点(但不用于介绍)。addAdvisor()AdvisorDefaultPointcutAdvisor

默认情况下,即使代理一次也可以添加或删除顾问或拦截器 已创建。唯一的限制是无法添加或删除 Introduction Advisor,因为工厂的现有代理不显示界面 改变。(您可以从工厂获取新的代理以避免此问题。

以下示例演示如何将 AOP 代理强制转换为接口,并检查 操纵其建议:Advised

  • Java

  • Kotlin

Advised advised = (Advised) myObject;
Advisor[] advisors = advised.getAdvisors();
int oldAdvisorCount = advisors.length;
System.out.println(oldAdvisorCount + " advisors");

// Add an advice like an interceptor without a pointcut
// Will match all proxied methods
// Can use for interceptors, before, after returning or throws advice
advised.addAdvice(new DebugInterceptor());

// Add selective advice using a pointcut
advised.addAdvisor(new DefaultPointcutAdvisor(mySpecialPointcut, myAdvice));

assertEquals("Added two advisors", oldAdvisorCount + 2, advised.getAdvisors().length);
val advised = myObject as Advised
val advisors = advised.advisors
val oldAdvisorCount = advisors.size
println("$oldAdvisorCount advisors")

// Add an advice like an interceptor without a pointcut
// Will match all proxied methods
// Can use for interceptors, before, after returning or throws advice
advised.addAdvice(DebugInterceptor())

// Add selective advice using a pointcut
advised.addAdvisor(DefaultPointcutAdvisor(mySpecialPointcut, myAdvice))

assertEquals("Added two advisors", oldAdvisorCount + 2, advised.advisors.size)
修改建议是否可取(没有双关语)是值得怀疑的 生产中的业务对象,尽管毫无疑问存在合法的用例。 但是,它在开发中(例如,在测试中)非常有用。我们有时有 发现能够以拦截器或其他形式添加测试代码非常有用 建议,进入我们想要测试的方法调用。(例如,建议可以 进入为该方法创建的事务,也许可以运行 SQL 来检查 在将事务标记为回滚之前,数据库已正确更新。

根据您创建代理的方式,您通常可以设置一个标志。在那 case,该方法返回 ,以及任何修改的尝试 通过添加或删除的建议会导致 .能力 在某些情况下,冻结建议对象的状态很有用(例如,到 防止调用代码删除安全拦截器)。frozenAdvisedisFrozen()trueAopConfigException