Announcement Announcement Module
Collapse
No announcement yet.
before and after advices in a single class? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • before and after advices in a single class?

    I created a class that implements both before and after advices:

    public class SimpleTracer implements AfterReturningAdvice, MethodBeforeAdvice {...}

    However when I register it as an interceptor with ProxyFactoryBean, it only functions as before advice. Am I doing something wrong?

  • #2
    Can you post some config examples and / or any relevant log messages?

    Comment


    • #3
      I think this is conceptually problematic. If you need a before and an after part in the same type, why not using AroundAdvice?

      Regards,
      Andreas

      Comment


      • #4
        Originally posted by markstgodard
        Can you post some config examples and / or any relevant log messages?
        Relevant config fragments:

        Code:
        	<bean id="enrollmentServiceImpl"
        		class="org.springframework.aop.framework.ProxyFactoryBean">
        		<property name="proxyInterfaces">
        			<value>
        				mypkg.IEnrollmentService
        			</value>
        		</property>
        		<property name="target">
        			<bean
        				class="mypkg.MockupEnrollmentServiceImpl" />
        		</property>
        		<property name="interceptorNames">
        			<list>
        				<value>tracer</value>
        			</list>
        		</property>
        	</bean>
        
        	<bean id="tracer"
        		class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        		<property name="advice">
        			<bean class="mypkg.SimpleTracer" />
        		</property>
        		<property name="pattern">
        			<value>.*</value>
        		</property>
        	</bean>
        Log messages:
        Code:
        12-Jul-2005 10&#58;06&#58;02 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
        INFO&#58; Pre-instantiating singletons in factory &#91;org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans &#91;enrollmentServiceImpl,tracer&#93;; root of BeanFactory hierarchy&#93;
        12-Jul-2005 10&#58;06&#58;02 AM org.springframework.beans.factory.support.AbstractBeanFactory getBean
        INFO&#58; Creating shared instance of singleton bean 'enrollmentServiceImpl'
        12-Jul-2005 10&#58;06&#58;02 AM org.springframework.aop.framework.DefaultAopProxyFactory <clinit>
        INFO&#58; CGLIB2 not available&#58; proxyTargetClass feature disabled
        12-Jul-2005 10&#58;06&#58;02 AM org.springframework.beans.factory.support.AbstractBeanFactory getBean
        INFO&#58; Creating shared instance of singleton bean 'tracer'
        The advisor bean:
        Code:
        package mypkg;
        
        import java.lang.reflect.Method;
        
        import org.springframework.aop.AfterReturningAdvice;
        import org.springframework.aop.MethodBeforeAdvice;
        
        public class SimpleTracer implements AfterReturningAdvice, MethodBeforeAdvice  &#123;
        
            public void before&#40;Method method, Object&#91;&#93; args, Object target&#41; throws Throwable &#123;
                System.out.println&#40;"in ---> " + method.getName&#40;&#41;&#41;;
            &#125;
        
            public void afterReturning&#40;Object returnValue, Method method, Object&#91;&#93; args, Object target&#41; throws Throwable &#123;
                System.out.println&#40;"out <--- " + method.getName&#40;&#41;&#41;;
            &#125;
        
        &#125;
        When I invoke a method on the enrollmentServiceImpl bean, only the "before" method of the SimpleTracer gets invoked.

        Comment


        • #5
          Originally posted by Andreas Senft
          I think this is conceptually problematic. If you need a before and an after part in the same type, why not using AroundAdvice?
          It seems to me that AroundAdvice is more appropriate when there is a need to control the method invocation.

          Comment


          • #6
            When I invoke a method on the enrollmentServiceImpl bean, only the "before" method of the SimpleTracer gets invoked...Am I doing something wrong?
            It appears you can only have one advice type per class. Spring retrieves an advisor in this order: Interceptor, BeforeAdvice, AfterAdvice and then ThrowsAdvice (see DefaultAdvisorAdapterRegistry.getInterceptor(..)). So if you define BeforeAdvice and AfterAdvice, Spring will only use the BeforeAdvice advice.

            It seems to me that AroundAdvice is more appropriate when there is a need to control the method invocation.
            Around advice is needed if you need to change the object returned. It's also slightly more risky, because it is up to the developer to invoke the target and return the object. You could also just consider using separate Before and After advice (in different classes).

            Comment


            • #7
              Originally posted by katentim
              Around advice is needed if you need to change the object returned.
              That is true, but that does not mean that you cannot use it in other cases as well (no one forces you to change the return object in an around advice ). If I want to perform code before and after an invocation I find it to be a good choice. Afaik some interceptors provided by Spring use also AroundAdvice (i.e. MethodInterceptor) without toying around with the return value.

              Originally posted by katentim
              It's also slightly more risky, because it is up to the developer to invoke the target and return the object.
              I agree. But you are the developer and you should know what you are doing :P

              Originally posted by katentim
              You could also just consider using separate Before and After advice (in different classes).
              If the before code has nothing to do with the after code that is perfectly legal, leveraging reusability. Otherwise I would refrain from artificial distinctions.

              Another option is, to provide an abstract MethodInterceptor implementation that does the proceed invocation and provides callback hooks before and afterwards (using the template method pattern).

              Regards,
              Andreas

              Comment


              • #8
                But you are the developer and you should know what you are doing
                Agreed. Just providing the word of warning.

                Comment


                • #9
                  All,

                  I committed a fix for this into CVS today and it has been scheduled for release in 1.2.3.

                  Regards,

                  Rob

                  Comment


                  • #10
                    I committed a fix for this into CVS today
                    Cheers - beat me to it. I think this is the best solution.

                    Comment

                    Working...
                    X