Results 1 to 6 of 6

Thread: Needs help for AoP implementation with Spring

  1. #1
    Join Date
    Dec 2006
    Posts
    3

    Default Needs help for AoP implementation with Spring

    This is my very first time to use Spring. I’m having trouble in my AoP implementation. What I’m doing is simple: one interface called Knight with one method getMyFavouratePizza(), the implementation of this interface is KnightImpletation. To feel Spring’s AoP, I am going to add a simple logging feature to the getMyFavouratePizza() method by AoP, therefore, I use MethodBeforeAdvice interface here. But the result is frustrating. It seems that the AoP has never been invoked by Spring. The following is my xml configuration file: (note: I’m using NameMatchMethodPointcut for the PointCut, but when I change to RegexpMethodPointcutAdvisor, it’s the same. Nothing happens.)

    Just wondering if miss anything here. Or could anyone help me out?


    <?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="knightTarget" class="com.knight.KnightImpletation">
    <property name="pizzaStrore">
    <ref local="pizzaMaker"/>
    </property>
    </bean>

    <bean id="pizzaMaker" class="com.knight.DominoPizza">
    <constructor-arg>
    <value>DominoPizza</value>
    </constructor-arg>
    </bean>

    <bean id="knightLogAdvice" class="com.knight.KnightBeforeInterceptor"/>

    <bean id="knightLogAdvisor" class="org.springframework.aop.support.NameMatchMe thodPointcut">
    <property name="mappedName">
    <value>getMyFavouratePizza</value>
    </property>
    <property name="advice">
    <ref bean="knightLogAdvice"/>
    </property>
    </bean>

    <bean id="knight" class="org.springframework.aop.framework.ProxyFact oryBean">
    <property name="proxyInterfaces">
    <list>
    <value>com.knight.Knight</value>
    </list>
    </property>
    <property name="interceptorNames">
    <list>
    <ref bean="knightLogAdvisor"/>
    </list>
    </property>
    <property name="target">
    <ref bean="knightTarget"/>
    </property>
    </bean>

    </beans>

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    From where are you calling the getMyFavouratePizza method? You probably invoke it on the non-proxied object, hence nothing is being intercepted.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3
    Join Date
    Dec 2006
    Posts
    3

    Default

    Quote Originally Posted by mdeinum View Post
    From where are you calling the getMyFavouratePizza method? You probably invoke it on the non-proxied object, hence nothing is being intercepted.
    Hi, Marten:

    thanks for your quick replying. so what do you mean here by non-proxied object?

    1) I have the implementation class, which is also the target class here:
    package com.knight;

    import org.apache.log4j.Logger;

    public class KnightImpletation implements Knight{
    PizzaStrore pizzaStrore;

    public Pizza getMyFavouratePizza() {
    return this.pizzaStrore.makePizza();
    }

    public void setPizzaStrore (PizzaStrore store){
    this.pizzaStrore = store;
    }

    }

    2) the advice class is like this:
    public class KnightBeforeInterceptor implements MethodBeforeAdvice{

    public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
    // TODO Auto-generated method stub
    System.out.println("=============== this is inside before ============");
    Logger logger = Logger.getLogger(arg2.getClass());
    logger.debug("Hi, welcome to Pizza World!");
    }

    }

    3) the test class is like this:
    public class KnightTest {
    /**
    * @param args
    */
    public static void main(String[] args) throws Exception {
    BeanFactory factory = new XmlBeanFactory(new FileSystemResource("knight.xml"));
    Knight knight = (KnightImpletation) factory.getBean("knightTarget");
    System.out.println(knight.getMyFavouratePizza());
    }
    }

    You will notice that in the test class, I call this getMyFavouratePizza(() method, and system.out some message, the IoC is working properly. But AoP is not working, which means the advice in the (2) is never invoked.

    what's the problem?

    thanks much,

  4. #4
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    What Marten is saying is, the bean your looking up is knightTarget. The ProxyFactoryBean knight, wraps the knightTarget with inteceptors, in your case a logging one. If you look up knight instead, the interceptors will be fired as knightTarget is proxied.

    Might be worth having a read of the reference manual.
    http://www.springframework.org/docs/reference/aop.html
    Last edited by karldmoore; Dec 6th, 2006 at 02:55 PM. Reason: typo

  5. #5
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    Just looking at your applicationContext.xml there are also some problems with it. I've fixed it, it should work now.

    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="knightTarget" class="com.knight.KnightImpletation"> <property name="pizzaStrore"> <ref local="pizzaMaker"/> </property> </bean>
    <bean id="pizzaMaker" class="com.knight.DominoPizza"> <constructor-arg> <value>DominoPizza</value> </constructor-arg> </bean>
    <bean id="knightLogAdvice" class="com.knight.KnightBeforeInterceptor"/>
    <bean id="knightLogAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <property name="mappedName"> <value>getMyFavouratePizza</value> </property> <property name="advice"> <ref bean="knightLogAdvice"/> </property> </bean>
    <bean id="knight" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <list> <value>com.knight.Knight</value> </list> </property> <property name="interceptorNames"> <list> <value>knightLogAdvisor</value> </list> </property> <property name="target"> <ref bean="knightTarget"/> </property> </bean>
    </beans>

  6. #6
    Join Date
    Dec 2006
    Posts
    3

    Default

    Yes. Got it work.

    the problem is when I invoked the target method, I needed to look up the proxied object, here is "knight", instead of target object "knightTarget". So in the KightTest.java file, I modifed the original one "Knight knight = (KnightImpletation) factory.getBean("knightTarget");
    " to:
    Knight knight = (Knight) factory.getBean("knight");

    then, everything works well.

    thanks so much karldmoore and Marten for your kind help.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •