Spring源碼窺探之:AOP註解

AOP也就是咱們平常說的@面向切面編程,看概念比較晦澀難懂,難懂的是設計理念,以及這樣設計的好處是什麼。在Spring的AOP中,經常使用的幾個註解以下:@Aspect,@Before,@After,@AfterReturning,@AfterThrowing,@Around,@PointCut以及@EnableAspectJAutoProxyspring

1. 模擬業務類CalculateService編程

/**
 * description:模擬業務類
 *
 * @author 70KG
 * @date 2018/12/17
 */
public class CalculateService {

    public int calculate(int i, int j) {
        int result = i / j;
        System.out.println("---->CalculateService-業務方法執行。。。。。。");
        return result;
    }

}

2. 編寫切面類,切面類必須標註它爲切面類(@Aspect),關於切入點表達式,能夠參考官方文檔,寫法不少種,還有關於JoinPoint這個參數必須放在第一位,不然報錯。測試

/**
 * description:日誌切面類,JoinPoint必須在參數的第一位
 *
 * @author 70KG
 * @date 2018/12/17
 */
@Aspect // ---> 聲明此類是一個切面類
public class LogAdvice {

    @Pointcut("execution(* com.nmys.story.springCore.springaop.sample01.CalculateService.*(..))")
    public void pointCut() {
    }

    /**
     * 目標方法執行前執行
     */
    @Before("pointCut()")
    public void logBefore(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        Object[] args = joinPoint.getArgs();
        System.out.println("---->" + signature + "方法執行前,傳入的參數是:" + Arrays.asList(args));
    }

    /**
     * 目標方法執行後執行
     */
    @After("pointCut()")
    public void logAfter(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        Object[] args = joinPoint.getArgs();
        System.out.println("---->" + signature + "方法執行後,傳入的參數是:" + Arrays.asList(args));

    }

    /**
     * 方法發生異常時執行
     */
    @AfterThrowing(value = "pointCut()", throwing = "ex")
    public void logException(JoinPoint joinPoint, Exception ex) {
        Signature signature = joinPoint.getSignature();
        System.out.println("---->" + signature + "方法執行後,拋出了異常信息:" + ex.getMessage());
    }


    /**
     * 正常返回時執行
     */
    @AfterReturning(value = "pointCut()", returning = "result")
    public void logReturn(JoinPoint joinPoint, Object result) {
        Signature signature = joinPoint.getSignature();
        System.out.println("---->" + signature + "方法執行後,返回的結果是:" + result);
    }

}

3. 配置類spa

/**
 * description
 *
 * @author 70KG
 * @date 2018/12/17
 */
@Configuration
@EnableAspectJAutoProxy // ---> 開啓切面的自動代理
public class MyConfig {

    @Bean
    public CalculateService calculateService() {
        return new CalculateService();
    }

    // 將切面類也交給容器管理
    @Bean
    public LogAdvice logAdvice() {
        return new LogAdvice();
    }

}

4. 測試類設計

/**
 * description
 *
 * @author 70KG
 * @date 2018/12/17
 */
public class Test01 {

    public static void main(String[] args) {

        // 加載配置文件
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MyConfig.class);
        CalculateService calc = (CalculateService) ac.getBean("calculateService");
        calc.calculate(4,2);
    }

}

5. 結果代理

---->int com.nmys.story.springCore.springaop.sample01.CalculateService.calculate(int,int)方法執行前,傳入的參數是:[4, 2]
---->CalculateService-業務方法執行。。。。。。
---->int com.nmys.story.springCore.springaop.sample01.CalculateService.calculate(int,int)方法執行後,傳入的參數是:[4, 2]
---->int com.nmys.story.springCore.springaop.sample01.CalculateService.calculate(int,int)方法執行後,返回的結果是:2
相關文章
相關標籤/搜索