Spring AOP 本質(4)

Spring AOP 本質(4)
 
這一主要看看Spring AOP是如何實現通知包圍的。
 
Spring AOP包圍通知在功能上和前置通知加後置通知相似,但仍是有區別的:包圍通知能夠修改返回值,還能夠阻止、替換目標方法的執行。
 
Spring裏的包圍通知是實現MethodInterceptor接口的攔截器。
 
Spring包圍通知有着很普遍的應用,好比遠程代理和事務管理,都是由攔截器完成。另外,攔截器也是剖析程序運行的好方法。
 
下面利用Spring AOP包圍通知實現監控業務方法的執行運行過程耗時狀況。
 
/**
* 業務組件
*/

public class WorkerBean {

     public void doSomeWork( int noOfTimes) {
         for( int x = 0; x < noOfTimes; x++) {
            work();
        }
    }
    
     private void work() {
        System.out.print("");
    }
}
 
import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.util.StopWatch;

/**
* 攔截器,實現方法包圍通知
*/

public class ProfilingInterceptor implements MethodInterceptor {

     public Object invoke(MethodInvocation invocation) throws Throwable {
         //啓動一個 stop watch
        StopWatch sw = new StopWatch();
         //運行計時器
        sw.start(invocation.getMethod().getName());
         //執行業務方法
        Object returnValue = invocation.proceed();
         //中止計時器
        sw.stop();
         //垃圾信息輸出
        dumpInfo(invocation, sw.getTotalTimeMillis());
         //返回業務方法返回值
         return returnValue;
    }

     /**
     * 垃圾信息輸入方法,實際上輸出的是方法運行的計時信息
     */

     private void dumpInfo(MethodInvocation invocation, long ms) {
         //獲取被調用方法
        Method m = invocation.getMethod();
         //獲取被調用方法所屬的對象
        Object target = invocation.getThis();
         //獲取被調用方法的參數
        Object[] args = invocation.getArguments();

        System.out.println( "所執行的方法: " + m.getName());
        System.out.println( "對象的類型: " + target.getClass().getName());

        System.out.println( "方法的參數:");
         for ( int x = 0; x < args.length; x++) {
            System.out.print( "    > " + args[x]);
        }
        System.out.print( "\n");

        System.out.println( "抓取方法運行的時間: " + ms + " ms");
    }
}
 
import org.springframework.aop.framework.ProxyFactory;

/**
* 客戶端測試方法
*/

public class ProfilingExample {

     public static void main(String[] args) {
         //建立代理對象
        WorkerBean bean = getWorkerBean();
         //在代理對象上調用業務方法
        bean.doSomeWork(10000000);
    }

     /**
     * 代理對象工廠
     */

     private static WorkerBean getWorkerBean() {
         //建立目標對象
        WorkerBean target = new WorkerBean();
         //構建代理對象工廠
        ProxyFactory factory = new ProxyFactory();
        factory.setTarget(target);
        factory.addAdvice( new ProfilingInterceptor());

         //生產一個代理對象
         return (WorkerBean)factory.getProxy();
    }
}
 
運行結果:
- Using JDK 1.4 collections
所執行的方法: doSomeWork
對象的類型: com.apress.prospring.ch6.profiling.WorkerBean
方法的參數:
    > 10000000
抓取方法運行的時間: 3453 ms

Process finished with exit code 0
 
從輸出的結果中,能夠看到程序方法調用的方法名、參數、所屬類,以及執行方法所耗費的時間。
 
另外說一下org.springframework.util.StopWatch類,這是個計時器類,此工具類主要能夠獲取計時器類start()和stop()兩次方法調用間的時間。具體能夠查看Spring的API文檔。另外,我也在apache commons 包裏面也有org.apache.common.lang.time.StopWatch。
相關文章
相關標籤/搜索