Каким бы образом вы ни создавали прокси АОП, ими можно манипулировать ЧЕРЕЗ интерфейс org.springframework.aop.framework.Advised. Любой прокси АОП может быть приведен к этому интерфейсу, независимо от того, какие другие интерфейсы он реализует. Этот интерфейс включает следующие методы:

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

Метод getAdvisors() возвращает Advisor для каждого советника, перехватчика или другого типа совета, который был добавлен в фабрику. Если вы добавили Advisor, то возвращаемым советником по этому индексу будет объект, который вы добавили. Если вы добавили перехватчик или другой тип совета, Spring обернет его в советник со срезом, который всегда возвращает true. Таким образом, если вы добавили MethodInterceptor, советник, возвращаемый для этого индекса, будет DefaultPointcutAdvisor, который возвращает ваш MethodInterceptor и срез, совпадающий со всеми классами и методами.

Методы addAdvisor() могут быть использованы для добавления любого Advisor. Обычно советником, содержащим срез и совет, является общий DefaultPointcutAdvisor, который можно использовать с любым советом или срезом (но не для введений).

По умолчанию можно добавлять или удалять советники или перехватчики даже после создания прокси. Единственным ограничением является невозможность добавления или удаления советника введений, так как существующие прокси из фабрики не показывают изменений интерфейса. (Чтобы избежать этой проблемы, можно получить новый прокси из фабрики).

В следующем примере показано приведение прокси АОП к интерфейсу Advised, а также изучение и манипулирование его советом:

Java
Advised advised = (Advised) myObject;
Advisor[] advisors = advised.getAdvisors();
int oldAdvisorCount = advisors.length;
System.out.println(oldAdvisorCount + " advisors");
// Добавляем совет, как перехватчик, без среза
// Будет соответствовать всем проксированным методам
// Может использоваться для советов "перехват", "перед", "после возврата" или "генерация исключения"
advised.addAdvice(new DebugInterceptor());
// Добавляем выбранный совет с помощью среза
advised.addAdvisor(new DefaultPointcutAdvisor(mySpecialPointcut, myAdvice));
assertEquals("Added two advisors", oldAdvisorCount + 2, advised.getAdvisors().length);
Kotlin
val advised = myObject as Advised
val advisors = advised.advisors
val oldAdvisorCount = advisors.size
println("$oldAdvisorCount advisors")
// Добавляем совет, как перехватчик, без среза
// Будет соответствовать всем проксированным методам
// Может использоваться для советов "перехват", "перед", "после возврата" или "генерация исключения"
advised.addAdvice(DebugInterceptor())
// Добавляем выбранный совет с помощью среза
advised.addAdvisor(DefaultPointcutAdvisor(mySpecialPointcut, myAdvice))
assertEquals("Added two advisors", oldAdvisorCount + 2, advised.advisors.size)
Нет уверенности, что можно советовать (случайный каламбур) изменять советы для бизнес-объекта в эксплуатационной среде, хотя, без сомнения, есть обоснованные случаи такой практики. Однако это может быть очень полезно при разработке (например, в тестах). Иногда мы находим очень полезной возможность добавить тестовый код в виде перехватчика или другого совета, попадая внутрь вызова метода, который хотим протестировать. (Например, совет может попасть внутрь транзакции, созданной для этого метода, возможно, для запуска SQL, чтобы проверить, что база данных была правильно обновлена, перед тем как пометить транзакцию для отката).

В зависимости от того, каким образом прокси был создан, обычно можно установить флаг frozen. В этом случае метод Advised isFrozen() возвращает true, а любые попытки изменить совет путем добавления или удаления приводят к AopConfigException. Возможность заморозить состояние снабженного советом объекта полезна в некоторых случаях (например, для предотвращения удаления вызывающим кодом перехватчика безопасности).