# 6.7操作被通知的对象

但是，你可以通过使用org.springframework.aop.framework.advised接口来创建AOP代理，从而对其进行操作。任何AOP代理都可以强制转换到此接口，不管它实现了哪个其他接口。此接口包括以下方法：

```java
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();
```

getAdvisors（）方法返回已添加到工厂的每个Advisor、拦截器或其他通知类型的顾问。如果添加了Advisor，则此索引处返回的advisor是你添加的对象。如果你添加了一个拦截器或其他通知类型，那么Spring将它包装在一个顾问中，并使用一个始终返回true的切入点。因此，如果添加了一个SystemInterceptor，则为该索引返回的Advisor是一个返回SystemInterceptor的DefaultPointcutAdvisor，以及一个匹配所有类和方法的切入点。

addAdvisor（）方法可用于添加任何Advisor。通常，持有切入点和建议的Advisor是DefaultPointcutAdvisor，你可以将其用于任何建议或切入点（但不用于introductions）。

默认情况下，即使创建了代理，也可以添加或删除顾问或拦截器。唯一的限制是不可能添加或删除简介顾问，因为工厂的现有代理不显示接口更改。（你可以从工厂获取新代理以避免此问题。）

下面的示例显示将AOP代理强制转换到Advised的接口，并检查和操作其advice：

```java
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);
```

> 尽管无疑存在合法的使用案例，但是否建议（不打算使用双关语）修改生产中业务对象的建议仍然存在疑问。但是，它在开发中非常有用（例如，在测试中）。我们有时发现，能够以拦截器或其他建议的形式添加测试代码，进入我们想要测试的方法调用中是非常有用的。（例如，在将事务标记为回滚之前，建议可以进入为该方法创建的事务中，或者运行SQL检查数据库是否正确更新。）

根据创建代理的方式，通常可以设置frozen标志。在这种情况下，Advised isfrozen（）方法返回true，任何通过添加或删除来修改通知的尝试都会导致AopConfigException。在某些情况下（例如，为了防止调用代码删除安全拦截器），冻结建议对象的状态的功能非常有用。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.flydean.com/spring-framework-documentation5/core-technologies/6.spring-aop-apis/6.7manipulating-advised-objects.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
