Get AOP proxy from the object itself

Is it possible to get the proxy object of this object in Spring? I need to call a subclass function. But, obviously, when I make a direct call, these aspects do not apply. Here is an example:

public class Parent { public doSomething() { Parent proxyOfMe = Spring.getProxyOfMe(this); // (please) Method method = this.class.getMethod("sayHello"); method.invoke(proxyOfMe); } } public class Child extends Parent { @Secured("president") public void sayHello() { System.out.println("Hello Mr. President"); } } 

I have found a way to achieve this. This works, but I think it is not very elegant:

 public class Parent implements BeanNameAware { @Autowired private ApplicationContext applicationContext; private String beanName; // Getter public doSomething() { Parent proxyOfMe = applicationContext.getBean(beanName, Parent.class); Method method = this.class.getMethod("sayHello"); method.invoke(proxyOfMe); } } 
+16
spring spring-aop aop
Sep 20 2018-11-11T00:
source share
3 answers

This hack is extremely inconvenient, please think about how to reorganize your code or use AspectJ weaving. You may feel warned, here is the solution

 AopContext.currentProxy() 

Javadoc I wrote about it here and here .

+13
Sep 20 '11 at 9:12
source share

AopContext.currentProxy() , as suggested by Tomas. A more general solution that will work outside the proxy class is to pass the object to org.springframework.aop.framework.Advised and get .getTargetSource().getTarget()

The first (getting a real object from a proxy object) is what you really don't need. On the other hand, getting the target proxy can be useful in some classes that check existing beans to add some features.

+12
Sep 20 '11 at 9:18
source share

You can use the bean post processor to set the proxy server link in the target bean. It moves Spring specifics from your beans to one class.

postprocessor

 import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class SelfReferencingBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof SelfReferencingBean) { ((SelfReferencingBean) bean).setProxy(bean); } return bean; } } 

Context

Register the postprocessor in applicationContext.xml .

 <bean id="srbpp" class="SelfReferencingBeanPostProcessor"/> 

Beans

Each bean must implement a SelfReferencingBean in order to tell the post processor that it needs a proxy link.

 public interface SelfReferencingBean { void setProxy(Object proxy) ; } 

Now we implement setProxy in each bean, which must call itself through its proxy.

 public class MyBean implements SelfReferencingBean { MyBean proxy; @Override public void setProxy(Object proxy) { this.proxy = (MyBean) proxy; } } 

You can put this last bit of code into the bean base class if you don't mind entering proxy in the bean type when calling methods directly on it. Since you are going through Method.invoke , you don’t even need to throw.

With a little work, I'm sure it could be converted to an a @Autowired annotation handler. Think about it, I don’t remember, even if I tried to add self-esteem using @Autowired .

 public class MyBean implements SelfReferencingBean { @Autowired MyBean proxy; } 
+5
Jun 30 2018-12-12T00:
source share



All Articles