After Advice

After Advice會在目標方法執行之後被呼叫,您可以實現org.springframework.aop.AfterReturningAdvice介面來 實作After Advice的邏輯,AfterReturningAdvice介面於Spring中的定義如下:

   package org.springframework.aop;
   
   public interface AfterReturningAdvice extends Advice {
       void afterReturning(Object returnValue, Method m,
                Object[] args, Object target) throws Throwable;
   }

AfterReturningAdvice直接繼承自Advice介面,afterReturning()當中傳入的引數有目標方法的返回值、方法實例、 引數、與目標物件,afterReturning()方法傳回void,若您要中止接下來的應用程式流程,丟出例外是唯一的方式。

可以在 Before Advice 中介紹的例子當中,為HelloSpeaker的hello()方法呼叫之後,加上AfterReturningAdvice,首先定義一個LogAfterAdvice類別來實作AfterReturningAdvice介面:

   LogAfterAdvice.java
   package onlyfun.caterpillar;
   
   import java.lang.reflect.Method;
   import java.util.logging.Level;
   import java.util.logging.Logger;
   import org.springframework.aop.AfterReturningAdvice;
   
   public class LogAfterAdvice 
                   implements AfterReturningAdvice { 
       private Logger logger = 
           Logger.getLogger(this.getClass().getName()); 
   
       public void afterReturning(Object object, 
                              Method method, 
                              Object[] args, 
                              Object target) throws Throwable { 
           logger.log(Level.INFO, "method ends..." + method); 
      } 
   }

接著只要在beans-config.xml中增加After Advice的實例,以及在ProxyFactoryBean中的"interceptorNames"增加對LogAfterAdvice的參考,定義檔撰寫如下:

   beans-config.xml
   <?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="logBeforeAdvice" 
         class="onlyfun.caterpillar.LogBeforeAdvice"/> 
   
   <bean id="logAfterAdvice" 
         class="onlyfun.caterpillar.LogAfterAdvice"/> 
   
   <bean id="helloSpeaker" 
         class="onlyfun.caterpillar.HelloSpeaker"/> 
   
   <bean id="helloProxy" 
         class="org.springframework.aop.framework.ProxyFactoryBean"> 
       <property name="proxyInterfaces"> 
           <value>onlyfun.caterpillar.IHello</value> 
       </property> 
       <property name="target"> 
           <ref bean="helloSpeaker"/> 
       </property> 
       <property name="interceptorNames"> 
           <list> 
               <value>logBeforeAdvice</value> 
               <value>logAfterAdvice</value> 
           </list> 
       </property> 
   </bean> 
   </beans>

在定義中,除了之前設定的LogBeforeAdvice之外,還加入了LogAfterAdvice的記錄服務,其它的程式與 Before Advice 相同。