Get AOP proxy from the object itself

Solution 1:

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.

Solution 2:

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.

Solution 3:

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;
}