CodeGym/Java Course/Module 5. Spring/Manipulation of objects equipped with advice

Manipulation of objects equipped with advice

Available

However you create AOP proxies, they can be manipulated VIA the org.springframework.aop.framework.Advised interface. Any AOP proxy can be cast to this interface, regardless of what other interfaces it implements. This interface includes the following methods:

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

The getAdvisors() method returns a Advisor for each advisor, interceptor, or other advice type that has been added to the factory. If you added Advisor, then the returned advisor for that index will be the object you added. If you added an interceptor or other type of advice, Spring will wrap it in a sliced adviser that always returns true. So if you added a MethodInterceptor, the advisor returned for that index would be a DefaultPointcutAdvisor, which returns your MethodInterceptor and a slice matching all classes and methods.

The addAdvisor() methods can be used to add any Advisor. Typically, the advisor that contains the slice and tip is the generic DefaultPointcutAdvisor, which can be used with any tip or slice (but not for introductions).

By default, you can add or remove advisors or interceptors even after creating a proxy. The only limitation is that it is not possible to add or remove an introduction advisor, since existing proxies from the factory do not show interface changes. (To avoid this problem, you can obtain a new proxy from the factory.

The following example shows casting an AOP proxy to the Advised interface and examining and manipulating its advice:

Java
Advised advised = (Advised) myObject;
Advisor[] advisors = advised.getAdvisors();
int oldAdvisorCount = advisors.length;
System.out.println(oldAdvisorCount + " advisors");
// Add the tip as an interceptor, without cutting
// Will match all proxied methods
// Can be used for "catch", "before", "after return" or "throw exception" advice
advised.addAdvice(new DebugInterceptor());
// Add the selected tip using a slice
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")
// Add the tip as an interceptor, without cutting
// Will match all proxied methods
// Can be used for "catch", "before", "after return" or "throw exception" advice
advised.addAdvice(DebugInterceptor())
// Add the selected tip using a slice
advised.addAdvisor(DefaultPointcutAdvisor(mySpecialPointcut, myAdvice))
assertEquals("Added two advisors", oldAdvisorCount + 2, advised.advisors.size)
It is not certain that it is advisable (pun intended) to change advice for a business entity in production, although there are no doubt legitimate cases of such practice. However, it can be very useful during development (for example, in tests). Sometimes we find it very useful to be able to add test code in the form of an interceptor or other advice, getting inside the method call we want to test. (For example, the tip could get inside a transaction created for this method, perhaps running SQL to check that the database was updated correctly before marking the transaction for rollback.)

Depending on how the proxy was created, you can usually set the frozen flag. In this case, the Advised isFrozen() method returns true, and any attempts to change the advice by adding or deleting result in an AopConfigException. The ability to freeze the state of an advised object is useful in some cases (for example, to prevent the caller from removing a security hook).

Comments
  • Popular
  • New
  • Old
You must be signed in to leave a comment
This page doesn't have any comments yet