Announcement Announcement Module
Collapse
No announcement yet.
Prbolem with DefaultAutoProxyCreator (Advice called twice) Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Prbolem with DefaultAutoProxyCreator (Advice called twice)

    I want to add custom annotations to my application and I want autoproxycreation for beans annotated with that annotation (at method level).

    whats the easiest add additional annotations for auto-proxy generation?

    (im not allowed to post links to other sites until i have 5 posts - so source coming soon

  • #2
    I started with a simple 'beforeMethodAdvisor' using the DefaultAutoProxyCreator. In my simple test the 'beforeMethodAdvice' is called twice per invokation.

    BeforeMethodAdvisor:
    Code:
    public class BeforeMethodAdvisor extends StaticMethodMatcherPointcutAdvisor{
    
        public BeforeMethodAdvisor() {
            this.setAdvice(new MyBeforeMethodAdvice());
        }
    
        public boolean matches(Method method, Class cls) {
            return ("doSomething".equals(method.getName()) && ISomeBean.class.isAssignableFrom(cls));
        }
    
        public class MyBeforeMethodAdvice implements MethodBeforeAdvice {
            public void before(Method method, Object[] args, Object target)
                throws Throwable {
                System.out.println("Before method: " + method.getName() + ", target=" + target);
            }
        }
    ISomeBean + SomeBean
    Code:
    public interface ISomeBean {
    
        void doSomething();
    }
    
    public class SomeBean implements ISomeBean {
        public void doSomething() {
            System.out.println("doing something....");
        }
    }
    spring-config
    Code:
    <bean id="beforeMethodAdvisor" class="some.package.BeforeMethodAdvisor"/>
    <bean name="myProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
          <property name="interceptorNames">
              <list>
                  <value>beforeMethodAdvisor</value>
              </list>
          </property>
    </bean>
    <bean id="someBean" class="some.package.SomeBean"/>
    unit-test and output
    Code:
    public class SomeTest {
    
        @Autowired
        private ISomeBean someBean;
    
        @Test
        public void doTest() {
            someBean.doSomething();
        }
    }
    
    Before method: doSomething, target=com.bearingpoint.ta.opennet.core.service.semaphore.SomeBean@156b6b9
    Before method: doSomething, target=[email protected]b9
    doing something....
    can someone explain why the advice gets called twice? what am i missing here?

    whats the easiest add additional annotations for auto-proxy generation?

    thank you,
    dani

    Comment


    • #3
      I assume that advice method is called twice because bean method is called twice. Anyway, it very easy to detect via debugger.

      You can define annotation based aspects (proxies constructions is implied from that) via @target pointcut designator. See 6.2.3.1. Supported Pointcut Designators:
      @target - limits matching to join points (the execution of methods when using Spring AOP) where the class of the executing object has an annotation of the given type

      Comment


      • #4
        I just had to try this and if I append this
        in the Test class:

        Code:
         if(someBean instanceof Advised) {
        	  for(Advisor advisor :((Advised)someBean).getAdvisors()) {
        		  System.out.println(advisor);
        	  }
          }
        I get this result:
        lab.BeforeMethodAdvisor@f4f44a
        lab.BeforeMethodAdvisor@f4f44a

        So, it is definitely getting adviced twice.

        Comment


        • #5
          My fault, didn't notice the problem from the first glance. You have two advisors there - the first one is created because of autoproxying, i.e. there is a bean 'beforeMethodAdvisor' defined at the context and it is applied due to autoproxying. The second advisor is created because 'interceptorNames' property is specified at DefaultAdvisorAutoProxyCreator bean definition.

          AbstractAutoProxyCreator.setInterceptorNames():
          Set the common interceptors. These must be bean names in the current factory. They can be of any advice or advisor type Spring supports.

          If this property isn't set, there will be zero common interceptors. This is perfectly valid, if "specific" interceptors such as matching Advisors are all we want.
          I.e. you may remove 'interceptorNames' property definition from the config and everythin is ok.

          Comment


          • #6
            thank you,
            dani

            Comment

            Working...
            X