AOP的簡單代碼實現

1、AOP的概念
A、連接點(JoinPoint)
業務代碼與服務器連接的位置

B、通知(Advice)
通知是連接點(JoinPoint)的具體行爲,有幾種通知:
1)置前通知
2)置後通知
3)環繞通知

C、切入點(PointCut)
橫切關注點(服務代碼)織入到哪些類中

D、切面(Aspect)
橫切關注點的實現叫切面
切面 = 切入點 + 通知
——前面的類B就是切面

E、目標對象(Target)
業務對象
——前面的類A就是目標對象

在代碼實現中,我們只要定義一個切面(Aspect)就可以了。
首先,我們定義一個切面類(HelloAspect):

public class HelloAspect {
    public void beforeService(){
        System.out.println("日誌開始了");
    }
    public void  afterService(){
        System.out.println("日誌結束了");
    }
    public void aroundService(ProceedingJoinPoint pjp){
        System.out.println("日誌開始時間"+new Date());
        try {
            pjp.proceed(); //執行業務方法
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        System.out.println("日誌結束時間"+ new Date());
    }
}

再定義一個業務類(HelloService):


public class HelloService {

    public void hello1(){
        System.out.println("我是類的業務方法1。。。");
    }
    public void hello2(){
        System.out.println("我是類的業務方法2");
    }
    public void hello3(){
        System.out.println("我是類的業務方法3");
    }

}

通過Schema來實現AOP

<bean id="HServie" class="cn.gson.springmavenTest.aspect.HelloService"></bean>
<bean id="HAspect" class="cn.gson.springmavenTest.aspect.HelloAspect"></bean>
    <aop:config>
        <aop:aspect ref="HAspect">
            <aop:before method="beforeService"
                pointcut="execution(* cn.gson.springmavenTest.aspect.HelloService.hello1(..))" />
            <aop:after method="afterService" 
               pointcut="execution(* cn.gson.springmavenTest.aspect.HelloService.hello2(..))"/>
            <aop:around method="aroundService"
               pointcut="execution(* cn.gson.springmavenTest.aspect.HelloService.hello3(..))"/>
        </aop:aspect>
    </aop:config>

測試:

ApplicationContext ac = 
            new ClassPathXmlApplicationContext("appaicationContext.xml");

    HelloService  hs =  ac.getBean(HelloService.class);
    hs.hello1();
    hs.hello2();
    hs.hello3();

運行結果:

日誌開始了
我是類的業務方法1。。。
我是類的業務方法2
日誌結束了
日誌開始時間Tue Jun 13 09:35:14 CST 2017
我是類的業務方法3
日誌結束時間Tue Jun 13 09:35:14 CST 2017

零配置的方式:

/**
 * 切面類
 */
@Component
@Aspect
public class HelloAspect {

    @Before(value="execution(* cn.gson.springmavenTest.aspect.HelloService.hello1(..))")
    public void beforeService(){
        System.out.println("日誌開始了");
    }
    @After(value="execution(* cn.gson.springmavenTest.aspect.HelloService.hello2(..))")
    public void  afterService(){
        System.out.println("日誌結束了");
    }
    @Around(value="execution(* cn.gson.springmavenTest.aspect.HelloService.hello3(..))")
    public void aroundService(ProceedingJoinPoint pjp){
        System.out.println("日誌開始時間"+new Date());
        try {
            pjp.proceed(); //執行業務方法
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        System.out.println("日誌結束時間"+ new Date());
    }
}

xml中開啓註解

<!-- 啓用AOP的註解 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    <bean id="HServie" class="cn.gson.springmavenTest.aspect.HelloService"></bean>
    <bean id="HAspect" class="cn.gson.springmavenTest.aspect.HelloAspect"></bean>

注意:
execution表達式
execution表達式是切入點(PointCut)中使用的一種模式,比如
execution(* com.sample.service.impl...(..))
第一個號:表示返回類型,號表示所有的類型。
包名:表示需要攔截的包名,後面的兩個句點表示當前包和當前包的所有子包,com.sample.service.impl包、子孫包下所有類的方法。
第二個號:表示類名,號表示所有的類。
(..):最後這個星號表示方法名,號表示所有的方法,後面括弧裏面表示方法的參數,兩個句點表示任何參數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章