tags:

views:

153

answers:

1

I need help making AOP work. What am I missing here?

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans 
   http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"&gt;

   <bean id="duke" class="com.tutorial.springidol.Singer">
      <constructor-arg value="Duke"/>
      <constructor-arg>
         <bean class="com.tutorial.springidol.Song">
            <property name="title" value="ABC"/>
     </bean>  
      </constructor-arg>
   </bean>  

   <bean id="audienceAdvice" class="com.tutorial.advice.AudienceAdvice">
 <property name="audience">
  <bean class="com.tutorial.springidol.Audience"/>
 </property>
   </bean>

   <bean id="audienceAdvisor"  
      class="org.springframework.
      aop.support.RegexpMethodPointcutAdvisor">

      <property name="advice" ref="audienceAdvice"/>
      <property name="pattern" value=".*perform"/>
  </bean>
 </beans>

AudienceAdvice.java

public class AudienceAdvice implements MethodBeforeAdvice,
                     AfterReturningAdvice {
    @Override
    public void before(Method arg0, Object[] arg1, Object arg2)
      throws Throwable {
     audience.takeSeats();
     audience.turnOffCellphones();
    }

    @Override
    public void afterReturning(Object arg0, Method arg1, Object[] arg2,
      Object arg3) throws Throwable {
     audience.applaud();
    }
    private Audience audience;
    public void setAudience(Audience audience) {
     this.audience = audience;
    }
}

The AOP does not work but the target executes though.

A: 

You've declared the target bean and the advice, but by default Spring doesn't know to actually apply the advice to the target.

You need to run an Autoproxy.

One way to do this:

<!--  Autoproxy -->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
 <property name="beanNames">
  <list>
   <value>duke</value>    
  </list>
 </property>

 <property name="interceptorNames">
  <list>
   <value>audienceAdvisor</value>
  </list>
 </property>
</bean>
Dick Chesterwood
(I should also say, this is an odd bean in that you don't need to look it up or wire it into any other bean. when you start up the container, the bean fires up and adds the advice to all the matching bean names). Just add this to your XML and as long as you're accessing your bean in the way toolkit describes, it should work.
Dick Chesterwood
This worked! But all this time I thought that it was the audience Advisor that applied the advice since it had the advice (advice property) and it knew when to apply it (the pattern property).
Jeune
The pattern property in the Advisor is describing the methods to apply to, not which beans to apply to.I find this confusing myself - I strongly recommend you investigate the aop: namespace, this allows you to configure in a much more intuitive fashion. Also, look at the AspectJ Pointcut syntax. Both topics are described in the reference manual.
Dick Chesterwood