Saurab Parakh
Saurab Parakh

Reputation: 1072

Is it proxy over a proxy when both Aspect and Transactional are used?

If I do use the transactional annotation over a method and at the same time also use the Aspect then how will spring behave for this? Will it create aspect proxy over the transaction proxy object? Or spring is that intelligent to mix up both proxy object's logic?

Please correct me if my understanding is totally wrong here.

Upvotes: 2

Views: 371

Answers (1)

Jose Luis Martin
Jose Luis Martin

Reputation: 10709

AOP Proxies are created by a BeanPostProcessor, the most specific one in AbstractAutoProxyCreator hirearchy with the following steps

  • Find Advices that can apply to a bean, see AopUtils.findAdvisorsThatCanApply().
  • Sort advisors with an OrderComparator, see AbstractAdvisorAutoProxyCreator.sortAdvisors().
  • Create the Proxy with the advisors.

So usually, only a proxy is involved.

However as Marten said if you create proxies by other ways that are unknown for AutorProxyCreator, you can get proxies of proxies easily.

For example:

<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target" ref="target" />
    <property name="proxyTargetClass" value="true" />
    <property name="interceptorNames" value="tracer" />
</bean> 

<bean id="target" class="test.SomeBean" />

<bean id="tracer" class="test.Tracer" />

<aop:config proxy-target-class="true">
    <aop:advisor id="traceAdvisor" advice-ref="tracer" pointcut="execution (public * *(..))" />
</aop:config>

With

public class SomeBean {

    public void someMethod() {
        System.out.println("In someMethod");
    }

    public static void main(String[] args) {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/context.xml");
        SomeBean bean = (SomeBean) ctx.getBean("proxy");
        bean.someMethod();

    }
}

public class Tracer  implements MethodBeforeAdvice {

    @Override
    public void before(Method method, Object[] args, Object target)
            throws Throwable {
        System.out.println("About to execute [" + method.getName() + "]" +
            " on target [" + target.getClass().getName() + "]");

    }

}

Will output:

About to execute [someMethod] on target [test.SomeBean$$EnhancerByCGLIB$$428125af]
About to execute [someMethod] on target [test.SomeBean$$EnhancerByCGLIB$$ee348b75]
About to execute [someMethod] on target [test.SomeBean]
In someMethod

Upvotes: 2

Related Questions