Announcement Announcement Module
Collapse
No announcement yet.
pointcut never matches/advice never triggered spring-aop 1.2.6 Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • pointcut never matches/advice never triggered spring-aop 1.2.6

    Hi,
    following the example found here
    i wanted to adapt it to write an aspect to call an update() method on a given interface after any call to any method declared in a DAO interface, but
    the after returning advice is never triggered (or...the pointcut never matches, which is quite surprising).

    I followed step-by-step the tutorial, and came out with the following spring conf:

    Code:
    <!--SPRING AOP IN ACTION Bean configuration -->
    	<bean id="businesslogicbean"
    		class="org.springframework.aop.framework.ProxyFactoryBean">
    		<property name="proxyInterfaces">
    			<value>a.b.persistence.ArgomentoManagerDAO</value>
    		</property>
    		<property name="target">
    			<ref local="argManDao"/>
    		</property>
    		
    	</bean>
    	<!-- Advisor pointcut definition for after advice -->
    	<bean id="theUpdateAfterAdvisor"
    		class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
    		<property name="advice">
    			<ref local="updateAfterAdvice"/>
    		</property>
    		<property name="pattern">
    			<value>.*</value>
    		</property>
    	</bean>
    	<bean id="updateAfterAdvice"
    		class="a.b.c.UpdateAfterAdvice">
    		<property name="associazioniUpdater">
    			<ref bean="associazioniUpdater"/>
    		</property>
    	</bean>
           <bean id="argManDao"
    		class="a.b.persistence.ArgomentoManagerDAOHibernate">
    		<property name="sessionFactory">
    			<ref bean="sessionFactory"/>
    		</property>
    	</bean>
    where argManDAO bean class declaration looks like:
    Code:
    public class ArgomentoManagerDAOJdbc extends HibernateDaoSupport implements
    		ArgomentoManagerDAO {....}
    "a.b.c.UpdateAfterAdvice" is like this:
    Code:
    public class UpdateAfterAdvice 
       implements AfterReturningAdvice
    {
    	
    	AssociazioniUpdater associazioniUpdater;
    	
        public void afterReturning(Object object, 
                                 Method m, 
                                 Object[] args, 
                                 Object target) 
                                 throws Throwable
        {
           System.out.println("****after returning of method "+ m.getName());
           associazioniUpdater.updateAllAssociazioni();
        }
    
    	public AssociazioniUpdater getAssociazioniUpdater() {
    		return associazioniUpdater;
    	}
    
    	public void setAssociazioniUpdater(AssociazioniUpdater associazioniUpdater) {
    		this.associazioniUpdater = associazioniUpdater;
    	}
    }
    what is the problem? is it related to the order of instantiation of beans ? is it something wrong in the pointcut declaration?

    thanks alot,
    valerio

  • #2
    Need interceptorNames

    Looks like you forgot to configure the interceptor chain within the ProxyFactoryBean.

    Code:
    <bean id="businesslogicbean" class="org.springframework.aop.framework.ProxyFactoryBean">
    	<property name="proxyInterfaces">
    		<value>a.b.persistence.ArgomentoManagerDAO</value>
    	</property>
    	<property name="target">
    		<ref local="argManDao"/>
    	</property>
    	<property name="interceptorNames">
    		<list>
    			<value>theUpdateAfterAdvisor</value>
    		</list>
    	</property>
    </bean>
    Hope that's the answer ... good luck.

    -Sean

    Comment


    • #3
      It also seems a little curious why you would use a Regexp Pointcut Advisor and configure it with ".*". Why not just use the bare advice as the interceptor since you don't seem to want a pointcut at all?

      -Sean

      Comment


      • #4
        tried but no luck

        Hello Sean,
        i had removed the interceptorNames from the xml by mistake.
        Unfortunately, even with the following configuration, using the advice as interceptor didn't work, that is the code inside the body of the advice is never executed:

        Code:
        <bean id="businesslogicbean"
        		class="org.springframework.aop.framework.ProxyFactoryBean">
        		<property name="proxyInterfaces">
        			<value>it.chi.repubblica.persistence.ArgomentoManagerDAO</value>
        		</property>
        		<property name="target">
        			<ref local="argManDao"/>
        		</property>
        		<property name="interceptorNames">
        		<list>
        			<value>updateAfterAdvice</value>
        		</list>
        	</property>
        	</bean>
        	
        	<bean id="updateAfterAdvice"
        		class="it.chi.repubblica.clustering.UpdateAfterAdvice">
        		<property name="associazioniUpdater">
        			<ref bean="associazioniUpdater"/>
        		</property>
        	</bean>
        same applies for the same configuration using the regexp matching advise:
        Code:
        	<bean id="businesslogicbean"
        		class="org.springframework.aop.framework.ProxyFactoryBean">
        		<property name="proxyInterfaces">
        			<value>it.chi.repubblica.persistence.ArgomentoManagerDAO</value>
        		</property>
        		<property name="target">
        			<ref local="argManDao"/>
        		</property>
        		<property name="interceptorNames">
        		<list>
        			<value>updateAfterAdvice</value>
        		</list>
        	</property>
        	</bean>
        	<!-- Advisor pointcut definition for after advice -->
        	<bean id="theUpdateAfterAdvisor"
        		class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        		<property name="advice">
        			<ref local="updateAfterAdvice"/>
        		</property>
        		<property name="pattern">
        			<value>.*</value>
        		</property>
        	</bean>
        	<bean id="updateAfterAdvice"
        		class="it.chi.repubblica.clustering.UpdateAfterAdvice">
        		<property name="associazioniUpdater">
        			<ref bean="associazioniUpdater"/>
        		</property>
        	</bean>
        Do i need to turn some feature on ?

        Comment


        • #5
          Stumped

          Unfortunately that leaves us both scratching our heads. I'm running against 1.2.6 as well. I'll try a similar setup and see what I run into.

          -Sean

          Comment


          • #6
            Here's a configuration that worked for me.

            I wired up an AfterReturning advice to my DAO as described below and it works just fine. Maybe there will be something helpful in the approach that I took, but it seems fairly equivalent to yours (other than the fact that it's working ).

            The Advice:
            Code:
            public class DaoTrace implements AfterReturningAdvice
            {
            	//------------------------------------------------------------------------------------------------
            	// public instance methods
            	//------------------------------------------------------------------------------------------------
            	
            	/**
            	 * @see AfterReturningAdvice#afterReturning(Object, Method, Object[], Object)
            	 */
            	public void afterReturning(Object result, Method method, Object[] arguments, Object target) 
            		throws Throwable
            	{
            		System.out.println("<<< Called: " + target.getClass().getName() + "#" + method.getName() + "(" + 
            			Arrays.toString(arguments).replace("[", "").replace("]", "") + ") >>>");
            		System.out.println("<<< Returning: " + result +	" >>>");
            	}//method afterReturning()
            
            }//class DaoTrace
            The DAO:
            Code:
            public class HibernateMemberDao extends HibernateDaoSupport implements MemberDao
            {
            	...
            }//class HibernateMemberDao
            The Configuration:
            Code:
            <?xml version="1.0" encoding="UTF-8"?>
            <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
            <beans>
            	
            	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            		<property name="configLocation">
            			<value>classpath:hibernate.cfg.xml</value>
            		</property>
            	</bean>
            	
            	<bean id="transactionManager"
            		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            		<property name="sessionFactory">
            			<ref bean="sessionFactory"/>
            		</property>
            	</bean>
            	
            	<bean id="daoTraceAdvice" class="com.ferrosoft.rounders.aop.DaoTrace"/>
            	
            	<bean id="memberDaoTarget"
            		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            		<property name="target">
            			<bean class="com.ferrosoft.rounders.dao.HibernateMemberDao">
            				<property name="sessionFactory">
            					<ref bean="sessionFactory"/>
            				</property>
            			</bean>
            		</property>
            		<property name="transactionManager">
            			<ref bean="transactionManager"/>
            		</property>
            		<property name="transactionAttributes">
            			<props>
            				<prop key="find*">PROPAGATION_REQUIRED, readOnly</prop>
            				<prop key="*">PROPAGATION_REQUIRED</prop>
            			</props>
            		</property>
            	</bean>
            	
            	<bean id="memberDao" class="org.springframework.aop.framework.ProxyFactoryBean">
            		<property name="proxyInterfaces">
            			<value>com.ferrosoft.rounders.dao.MemberDao</value>
            		</property>
            		<property name="target">
            			<ref bean="memberDaoTarget"/>
            		</property>
            		<property name="interceptorNames">
            			<list>
            				<value>daoTraceAdvice</value>
            			</list>
            		</property>
            	</bean>
            	
            	<bean id="eventDao" 
            		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            		<property name="target">
            			<bean class="com.ferrosoft.rounders.dao.HibernateEventDao">
            				<property name="sessionFactory">
            					<ref bean="sessionFactory"/>
            				</property>
            			</bean>
            		</property>
            		<property name="transactionManager">
            			<ref bean="transactionManager"/>
            		</property>
            		<property name="transactionAttributes">
            			<props>
            				<prop key="find*">PROPAGATION_REQUIRED, readOnly</prop>
            				<prop key="*">PROPAGATION_REQUIRED</prop>
            			</props>
            		</property>
            	</bean>
            	
            </beans>
            Obviously you don't need to include the transaction proxy if you don't need it. Not sure what the difference is between this and what you have. But, if you can find it, it just might be the ticket.

            -Sean

            Comment


            • #7
              still failing

              hi,
              i'm still not able to reproduce your example in my context. i can't see any relevant info, apart from some bean being internally defined instead of using reference ids.

              since i could have done some errors, i'll try to describe which are the beans involved:
              -this is a Manager that holds a reference to to a DAO object (implementing the ArgomentoManagerDAO interface):

              Code:
              <bean id="argMan" class="it.chi.repubblica.controller.ArgomentoManager">
              		<property name="argomentoManagerDAO">
              			<ref bean="argManDao"/>
              		</property>
              	</bean>
              -this is definition of the interface to be 'intercepted'
              Code:
              <bean id="argManDao"
              		class="org.springframework.aop.framework.ProxyFactoryBean">
              		<property name="proxyInterfaces">
              				<value>it.chi.repubblica.persistence.ArgomentoManagerDAO</value>
              		</property>
              		<property name="target">
              			<ref bean="argManDaoTarget"/>
              		</property>
              		<property name="interceptorNames">
              			<list>
              				<value>daoUpdateAdvice</value>
              			</list>
              		</property>
              	</bean>
              -this is the bean implementing the DAO interface:
              Code:
              <bean id="argManDaoTarget"
              	class="it.chi.repubblica.persistence.ArgomentoManagerDAOJdbc">
              	<property name="sessionFactory">
              		<ref bean="sessionFactory"/>
              	</property>
              </bean>
              - this is definition of the advice:
              Code:
              <bean id="daoUpdateAdvice"
              		class="it.chi.repubblica.clustering.UpdateAfterAdvice">
              		<property name="associazioniUpdater">
              			<ref bean="associazioniUpdater"/>
              		</property>
              	</bean>
              with the above beans definition, the code inside the after returning is never executed. any idea ?

              Comment


              • #8
                almost working...

                i finally got a configuration working, but i couln't get rid of the transactionManager..
                i'm pasting the conf, in case any one can suggest me a way to simplify the xml to get rid of the transaction manager ( i want to avoid it because I still don't know if and how I need it):

                Code:
                <bean id="argMan" class="it.chi.repubblica.controller.ArgomentoManager">
                		<property name="argomentoManagerDAO">
                			<ref bean="argManDao"/>
                		</property>
                	</bean>
                	<!--Definisco quale  l'interfaccia che definisce i metodi da intercettare:
                		per quuesto esempio, l'interfaccia  quella dell'argomentoManagerDAO-->
                	<bean id="argManDao"
                		class="org.springframework.aop.framework.ProxyFactoryBean">
                		<property name="proxyInterfaces">
                				<value>it.chi.repubblica.persistence.ArgomentoManagerDAO</value>
                		</property>
                		<property name="target">
                			<ref bean="argManDaoTarget"/>
                		</property>
                		<property name="interceptorNames">
                			<list>
                				<value>theDaoUpdateAdvice</value>
                			</list>
                		</property>
                	</bean>
                	<!-- Advisor pointcut definition for after advice -->
                	<bean id="theDaoUpdateAdvice"
                		class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
                		<property name="advice">
                			<ref local="daoUpdateAdvice"/>
                		</property>
                		<property name="patterns">
                			<list>
                				<value>.*setArgomento</value>
                				<value>.*deleteArgomento</value>
                				<value>.*updateArgomento</value>
                			</list>
                		</property>
                	</bean>
                	<!--il target del proxy-->
                	<bean id="argManDaoTarget" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
                		<property name="target">
                			<bean parent="abstractBaseDAO" class="it.chi.repubblica.persistence.ArgomentoManagerDAOJdbc"/>
                		</property>
                		<property name="transactionManager">
                			<ref bean="transactionManager"/>
                		</property>
                		<property name="transactionAttributes">
                			<props>
                				<prop key="find*">PROPAGATION_REQUIRED, readOnly</prop>
                				<prop key="*">PROPAGATION_REQUIRED</prop>
                			</props>
                		</property>
                	</bean>
                	<bean id="transactionManager"
                		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
                		<property name="sessionFactory">
                			<ref bean="sessionFactory"/>
                		</property>
                	</bean>
                	<bean id="daoUpdateAdvice" class="it.chi.repubblica.aop.UpdateAssociazioniAfterAdvice">
                		<property name="associazioniUpdater">
                			<ref bean="associazioniUpdater"/>
                		</property>
                	</bean>

                Comment

                Working...
                X