Announcement Announcement Module
Collapse
No announcement yet.
Newbie question - Advice methods not being called... Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Newbie question - Advice methods not being called...

    I'm currently working through Spring In Action 2nd ed., and have got as far as trying to get the basic Spring AOP functionality working - it compiles just fine, and the methods run, BUT, none of the advice methods work. I have a feeling I'm doing something very daft, could someone point it out to me, please?

    Here's the class I want to add the advice to:

    Code:
    package springinaction.springidol;
    
    
    public class Juggler implements Performer {
    
      private int beanbags;
    
      private Juggler(){}
    
      public void perform() throws PerformanceException
      {
        System.out.println("Juggling " + this.beanbags + " beanbags.");  
      }
    
      public int getBeanbags()
      {
        return beanbags;
      }
    
      public void setBeanbags(int beanbags)
      {
        this.beanbags = beanbags;
      }
    
    }
    Here's the class that should do things when the advice methods are called:
    Code:
    package springinaction.springidol;
    
    public class Audience{
    
    
      public void applaud()
      {
        System.out.println("CLAP CLAP CLAP");
    
      }
    
    
      public void demandRefund()
      {
        System.out.println("Booooooo, we want our money back.");
    
      }
    
    
      public void takeSeats()
      {
        System.out.println("The audience is taking their seats");
    
      }
    
    
      public void turnOffCellPhones()
      {
        System.out.println("The audience is turning off their cell phones");
    
      }
    
    }
    Here's my advice class:

    Code:
    package springinaction.springidol;
    
    import java.lang.reflect.Method;
    
    import org.springframework.aop.AfterReturningAdvice;
    import org.springframework.aop.MethodBeforeAdvice;
    import org.springframework.aop.ThrowsAdvice;
    
    public class AudienceAdvice implements 
      MethodBeforeAdvice,
      AfterReturningAdvice, 
      ThrowsAdvice {
    
    
      private Audience audience;
    
      public AudienceAdvice(){System.out.println("Invoked AudienceAdvice");}
    
    
      public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable
      {
        audience.takeSeats();
        audience.turnOffCellPhones();
      }
    
    
      public void afterReturning(Object arg0, Method arg1, Object[] arg2,
          Object arg3) throws Throwable
      {
        audience.applaud();
      }
    
    
      public void afterThrowing(Throwable throwable)
      {
        audience.demandRefund();
      }
    
      public void setAudience(Audience audience)
      {
        this.audience = audience;
      }
    
    }
    and here's my context xml:

    Code:
    <?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">
      
      <bean id="duke" class="springinaction.springidol.Juggler">
        <property name="beanbags" value="3"/>
      </bean>
      
      <bean id="audience" class="springinaction.springidol.Audience"/>
      
      <bean id="audienceAdvice" class="springinaction.springidol.AudienceAdvice">
        <property name="audience" ref="audience"/>
      </bean>
      
      <bean id="audienceAdvisor"
        class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        <property name="advice" ref="audienceAdvice" />
        <property name="pattern" value=".*perform" />
      </bean>
    </beans>
    As I understand it, there should be text written to standard out when the perform method of Juggler gets called, but this isn't happening...

  • #2
    The plot thickens...

    After running it through a version of ant that didn't come with eclipse (I know, I know...) I'm told that "advice", as I've specified in my context isn't writeable. After following the tree for JdkRegexpMethodPointcut up I can't find a "setAdvice" method anywhere.

    I'm using Spring 2.5 to build and run this, and I have a feeling that the example I'm working from is using an older version of the spring-AOP. I take it that attaching advice to the pointcut isn't done with a property of advice anymore - so how is it done?

    I'll be moving along to aspectJ and annotations soon enough, but I'd still like to fill this hole in my knowledge...

    Comment


    • #3
      And HOW are you calling/accessing your juggler? Simply specifing an xml and only loading it isn't going to do anything. Also you don't specify a ProxyFactoryBean or BeanNameAutoProxyCreator, you only have an advice but aren't binding the stuff together. Next to that make sure you use an ApplicationContext and not a BeanFactory.
      Last edited by Marten Deinum; Feb 26th, 2008, 01:04 AM.

      Comment


      • #4
        Heh - I'm new, but I ain't that new. There are a couple of classes I've not invluded, mainly the class containing the main() and some supporting objects - I'm using ClassPathXmlApplicationContext for my context.

        I know there aren't any proxies. There aren't meant to be - I though that Spring AOP was capable of acting as a wrapper to classes in simple cases. That's the functionality I'm trying to achieve...

        Comment


        • #5
          You need either a ProxyFactoryBean or a BeanNameAutoProxyCreator else nothing is going to happen for you. When using the aop namespace or annotations spring picks up a lot of stuff NOT with the basic AOP. You now have 2 objects/beans which are instantiated but don't do anything.

          Code:
          <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
          	<property name="interceptorNames">
          		<idref bean="audienceAdvice" />
          	</property>
          	<property name="beanNames">
          		<idref bean="duke" />
          	</property>
          </bean>
          If you add in a BNAPC like above, things get wired together. If you use a ProxyFactoryBean instead of a BNAPC make sure you use the PROXIED instance not the NON proxied instance (which is the target of the ProxyFactoryBean).

          Next time give the full information, so that we can see what you have and what you don't have.

          Comment

          Working...
          X