Is possible to get the proxy of a given object in Spring? I need to call a function of a subclass. But, obviously, when I do a direct call, the aspects aren\'t applied. Here
AopContext.currentProxy()
as suggested by Tomasz will work. A more generic solution, that will work outside of the proxied class is to cast the object to org.springframework.aop.framework.Advised
and get .getTargetSource().getTarget()
The former (getting the real object from the proxied object) is something that you should not really need. On the other hand getting the target proxy might be useful in some utility class that inspects existing beans in order to add some feature.
You can use a bean post-processor to set a reference to the proxy on the target bean. It moves the Spring-specifics from your beans to a single class.
Post-Processor
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 post-processor in applicationContext.xml
.
<bean id="srbpp" class="SelfReferencingBeanPostProcessor"/>
Beans
Each bean must implement SelfReferencingBean
to tell the post-processor that it needs a reference to the proxy.
public interface SelfReferencingBean {
void setProxy(Object proxy) ;
}
Now implement setProxy
in each bean that needs to call itself through its proxy.
public class MyBean implements SelfReferencingBean {
MyBean proxy;
@Override
public void setProxy(Object proxy) {
this.proxy = (MyBean) proxy;
}
}
You could put this last bit of code into a bean base class if you don't mind casting proxy
to bean's type when calling methods directly on it. Since you're going through Method.invoke
you wouldn't even need the cast.
With a little work I bet this could be converted to an annotation processor a la @Autowired
. Come to think of it, I don't recall if I even tried adding a self-reference using @Autowired
itself.
public class MyBean implements SelfReferencingBean {
@Autowired MyBean proxy;
}
This hack is extremely awkward, please consider refactoring your code or using AspectJ weaving. You may feel warned, here is the solution
AopContext.currentProxy()
JavaDoc. I blogged about it here and here.