1. 程式人生 > >Spring入門筆記之Aop

Spring入門筆記之Aop

                                                                       Spring入門筆記之Aop

                                                                                                      ——2018年11月22日

Aop(Aspect Oriented Programming),即面向切面程式設計,可以說是對oop(Object Oriented Programming),即面向物件程式設計的補充和完善。Aop的存在就是讓大量程式碼重複使用,將各個模組重用。

所謂“切面”,簡單來說就是那些與業務無關,卻為業務模組所共同呼叫的邏輯或責任封裝起來,便於減少系統的重複程式碼,降低模組之間的耦合度,並有利於未來的可操作性和可維護性。

AOP核心概念

  1. 橫切關注點

對哪些方法進行攔截,攔截後怎麼處理,這些關注點稱之為橫切關注點。

  1. 切面(aspect)

類是對物體特徵的抽象,切面就是對橫切關注點的抽象

  1. 連線點(join point)

被攔截到的點,因為Spring只支援方法型別的連線點,所以在Spring中連線點指的就是被攔截到的方法,實際上連線點還可以是欄位或者構造器.

       4、切入點(pointcut)

對連線點進行攔截的定義

5、通知(advice)

所謂通知指的就是指攔截到連線點之後要執行的程式碼,通知分為前置、後置、異常、最終、環繞通知五類

6、目標物件

代理的目標物件

7、織入(weave)

將切面應用到目標物件並導致代理物件建立的過程

8、引入(introduction)

在不修改程式碼的前提下,引入可以在執行期為類動態地新增一些方法或欄位.

程式碼瞭解階段:

Spring AOP代理物件的生成

Xml配置方式:

  1. 把目標方法所有類和切面類放入ioc容器中。
  2. 配置<aop:config>

這裡著重解釋講解第二種方式(註解)

步驟:

  1. spring框架中我們可以使用基於AspectJ註解來配置Aop(最主流)

簡單理解就是,AspectJ就是一個支援AOP的第三方元件,Spring提供了很好的支援,首先需要引入Maven依賴。

  1. 在配置檔案中宣告 使用AspectJ註解

使AspectJ註解生效:

Util類:

package org.robert.util;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class Log {

    /**
     *宣告此方法為了程式碼重用嘛
     */
    @Pointcut("execution(* org.robert.Service.*.*(..))")
    public void pointcut(){

    }
    
    /**
     * 前置通知
     * 進入方法就執行
     */
    @Before(value = "pointcut()")
    public void before(){
        System.out.println("進來了");
    }

    /**
     * 後置通知
     * 業務執行完成通知
     * 無論是否出異常就執行
     */
    @After(value = "pointcut()")
    public void after(){
        System.out.println("幹完了,要出去了");
    }

    /**
     * 業務方法執行失敗就不執行
     * 返回通知
     * 獲取返回的值
    // 宣告該方法為返回通知:方法正常執行結束後執行的程式碼
    // 返回 通知是可以訪問到方法的返回值的!
    /*切點表示式表示執行任意類的任意方法. 第
    一個 * 代表匹配任意修飾符及任意返回值,  第二個 * 代表任意類的物件,
    第三個 * 代表任意方法, 引數列表中的 ..  匹配任意數量的引數
    */
     */
    @AfterReturning(value = "pointcut()",returning = "val")
    public void success(Object val){
        System.out.println("業務執行成功"+val);
    }

    /**
     * 異常通知
     * 出異常就執行
     */
    @AfterThrowing(value = "pointcut()",throwing = "val")
    public void testexception(Throwable val){
        System.out.println("出異常啦"+val.getMessage());
    }

    /**
     * 環繞通知
     * 功能雖然強大,但用得少
     */
   //@Around(value = "pointcut()")
    public Object arroud(ProceedingJoinPoint pdj){
        //前置
        Object result = null;
        try {
            //執行目標方法
            result = pdj.proceed();
        } catch (Throwable e) {
            //異常
            e.printStackTrace();
        }
        //後置
        return result;
    }
}

Service類:

package org.robert.Service;

import org.robert.mapper.StudentMapper;
import org.springframework.stereotype.Service;

@Service
public class StudentService {

    StudentMapper studentMapper;

    public void testService() {
        System.out.println(studentMapper);
    }

    public Integer insert(){
        System.out.println("業務程式碼插入資料");
        //System.out.println(2/0);
        return 100;
    }

    public void delete(){
        System.out.println("業務程式碼刪除資料");
    }

}