Spring AOP的案例

jopen 10年前發布 | 19K 次閱讀 Spring JEE框架 Spring AOP

        因為初衷只是為了給代碼中加入一些日志,而我后來想到順便加上一個對service層的方法執行時間的統計。對于這個,衍生出一個線程安全問題,統計時間意味著在Before需要有一個變量去接收起始時間,在After時獲得之前的變量值進行計算并輸出。這樣一來之前的變量在并發情況下,后來的訪問的起始時間將會覆蓋這個變量值,想到ThreadLocal,泛型Long。由此解決線程安全問題。

        關于ThreadLocal,請自行google。

 

切面類

package com.eric.aop.aspect;

import java.lang.reflect.Method; import java.text.MessageFormat;

import org.springframework.aop.AfterReturningAdvice; import org.springframework.aop.MethodBeforeAdvice; import org.springframework.aop.ThrowsAdvice;

public class MyAspect implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice { private ThreadLocal<Long> tl=new ThreadLocal<Long>();

public void before(Method method, Object[] objArr, Object target)
        throws Throwable {
    // 獲得當前時間,set到ThreadLocal中
    tl.set(System.currentTimeMillis());
}

public void afterReturning(Object obj, Method method, Object[] objArr,
        Object target) throws Throwable {
    // 從ThreadLocal中get值并進行計算
    long runTime=System.currentTimeMillis()-tl.get();
    System.out.println(MessageFormat.format("{0}>>>本次耗時>>>{1}ms", 
            Thread.currentThread().getName(),runTime));
}
public void afterThrowing(Method method, Object[] objArr, Object target,
        Exception ex) throws Throwable {
    System.out.println("err>>>"+ex);
}

}</pre>

業務接口類

package com.eric.aop.service;

public interface VOService {         public void print(); }</pre>


業務實現類

package com.eric.aop.service.imp;

import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service;

import com.eric.aop.service.VOService;

@Service("vOService") @Scope("prototype") public class VOServiceImpl implements VOService {

public void print() {
    System.out.println("我是VO");
    try {
        Thread.sleep(new Random().nextInt(10000));
        // Object obj=null;
        // obj.toString();
    } catch (InterruptedException e) {
    }
}

}</pre>

Spring配置

<?xml version="1.0" encoding="UTF-8" ?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"  
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd     
    http://www.springframework.org/schema/context     
    http://www.springframework.org/schema/context/spring-context-2.5.xsd  
    http://www.springframework.org/schema/tx  
    http://www.springframework.org/schema/tx/spring-tx-2.5.xsd  
    http://www.springframework.org/schema/aop  
    http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">  
  
    <context:annotation-config />  
    <!-- 掃描com.eric 下所有的包-->  
    <context:component-scan base-package="com.eric" />  
  
    <bean id="testAdvice" class="com.eric.aop.aspect.MyAspect" />  
    <aop:config>  
       <aop:advisor pointcut="execution(* com.eric.aop.*.*Service.*(..))"  
            advice-ref="testAdvice" />  
    </aop:config>  
</beans>

測試類

package com.eric.aop.test;

import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.eric.aop.service.VOService;

public class AopTest { public static void main(String[] args) throws InterruptedException { ApplicationContext ac = new ClassPathXmlApplicationContext( "applicationContext.xml"); int t = 9; for (int i = 0; i < t; i++) { new Thread(new ThreadTest(ac)).start(); } } } class ThreadTest implements Runnable { private ApplicationContext ac;

public ThreadTest(ApplicationContext ac) {
    this.ac = ac;
}
public void run() {
    VOService vo = (VOService) ac.getBean("vOService");
    vo.print();
}

}</pre>

 

輸出結果

我是VO
我是VO
我是VO
我是VO
我是VO
我是VO
我是VO
我是VO
我是VO
Thread-7>>>本次耗時>>>292ms
Thread-2>>>本次耗時>>>1,387ms
Thread-5>>>本次耗時>>>1,707ms
Thread-1>>>本次耗時>>>2,686ms
Thread-9>>>本次耗時>>>4,874ms
Thread-3>>>本次耗時>>>5,173ms
Thread-6>>>本次耗時>>>6,033ms
Thread-8>>>本次耗時>>>9,379ms
Thread-4>>>本次耗時>>>9,740ms

來自:http://my.oschina.net/iseric/blog/290056

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!