1. 程式人生 > >springboot中aop(註解切面)應用

springboot中aop(註解切面)應用

aop的理解:我們傳統的程式設計方式是垂直化的程式設計,即A–>B–>C–>D這麼下去,一個邏輯完畢之後執行另外一段邏輯。但是AOP提供了另外一種思路,它的作用是在業務邏輯不知情(即業務邏輯不需要做任何的改動)的情況下對業務程式碼的功能進行增強,這種程式設計思想的使用場景有很多,例如事務提交、方法執行之前的許可權檢測、日誌列印、方法呼叫事件等等http://www.importnew.com/26951.html)

1.新增依賴

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>


2.切面類.

(1)指定切點

(2)這裡的涉及的通知型別有:前置通知、後置最終通知、後置返回通知、後置異常通知、環繞通知,在切面類中新增通知

package com.fcc.web.aop;

import com.fcc.domain.annotation.MyInfoAnnotation;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;


//描述切面類
@Aspect
@Component
public class TestAop {

    /*
     * 定義一個切入點
     */
    @Pointcut("@annotation(com.fcc.domain.annotation.MyInfoAnnotation)")
    public void myInfoAnnotation() {
    }


    // 用@Pointcut來註解一個切入方法
    @Pointcut("execution(* com.fcc.web.controller.*.**(..))")
    public void excudeController() {
    }

    /*
     * 通過連線點切入
     */
//    @Before("execution(* findById*(..)) &&" + "args(id,..)")
//    public void twiceAsOld1(Long id) {
//        System.out.println("切面before執行了。。。。id==" + id);
//
//    }


    //@annotation 這個你應當知道指的是匹配註解
    //括號中的 annotation 並不是指所有自定標籤,而是指在你的註釋實現類中 *Aspect 中對應註解物件的別名,所以別被倆 annotation  所迷惑。
    @Around(value ="myInfoAnnotation()&&excudeController()&&@annotation(annotation)")
    public Object twiceAsOld(ProceedingJoinPoint thisJoinPoint,
                             MyInfoAnnotation annotation
    ) {
        System.out.println(annotation.value());  
     thisJoinPoin.proceed();//環繞通知必須執行,否則不進入註解的方法
     return null;
}}

2.用以指定切點的註解

package com.fcc.domain.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.PARAMETER})
public @interface MyInfoAnnotation {
    String value() default "";
}
3.測試類
@Controller
@RequestMapping("business")
public class BusinessController {


    @MyInfoAnnotation(value = "FCC")
    @RequestMapping("/test")
    @ResponseBody
    public String testBusiness(){

        return "business";
    }
}
瀏覽器請求  localhost:8080/business/test
控制檯輸出:FCC注意:這裡用到了JoinPoint。通過JoinPoint可以獲得通知的簽名信息,如目標方法名、目標方法引數資訊等。ps:還可以通過RequestContextHolder來獲取請求資訊,Session資訊。