天天看點

spring基于 注解的 AOP 的前後置通知,異常通知,最終通知,環繞通知

1.IAccountService接口和實作類

package com.service;

/**
 * 賬戶業務層的接口
 */
public interface IAccountService {
    public void saveAccount() ;

}      
package com.service.impl;

import com.service.IAccountService;
import org.springframework.stereotype.Service;

/**
 * 賬戶的業務層實作類
 */
@Service("accountService")
public class AccountServiceImpl implements IAccountService{


    public void saveAccount() {
        System.out.println("執行了儲存");
//        int i=1/0;
    }
}      

2.Logger類

package com.utils;

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

@Component("logger")
@Aspect//表示目前類是一個切面類
public class Logger {

    @Pointcut("execution(* com.service.impl.*.*(..))")
    private void pt1(){}

    /**
     * 前置通知
     */
    @Before("pt1()")
    public  void beforePrintLog(){
        System.out.println("前置通知Logger類中的beforePrintLog方法開始記錄日志了。。。");
    }

    /**
     * 後置通知
     */
    @AfterReturning("pt1()")
    public  void afterReturningPrintLog(){
        System.out.println("後置通知Logger類中的afterReturningPrintLog方法開始記錄日志了。。。");
    }
    /**
     * 異常通知
     */
    @AfterThrowing("pt1()")
    public  void afterThrowingPrintLog(){
        System.out.println("異常通知Logger類中的afterThrowingPrintLog方法開始記錄日志了。。。");
    }

    /**
     * 最終通知
     */
    @After("pt1()")
    public  void afterPrintLog(){
        System.out.println("最終通知Logger類中的afterPrintLog方法開始記錄日志了。。。");
    }


    /**
     * 環繞通知
     */
//    @Around("pt1()")
    public Object aroundPringLog(ProceedingJoinPoint pjp){
        Object rtValue = null;
        try{
            Object[] args = pjp.getArgs();//得到方法執行所需的參數

            System.out.println("Logger類中的aroundPringLog方法開始記錄日志了。。。前置");

            rtValue = pjp.proceed(args);//明确調用業務層方法(切入點方法)

            System.out.println("Logger類中的aroundPringLog方法開始記錄日志了。。。後置");

            return rtValue;
        }catch (Throwable t){
            System.out.println("Logger類中的aroundPringLog方法開始記錄日志了。。。異常");
            throw new RuntimeException(t);
        }finally {
            System.out.println("Logger類中的aroundPringLog方法開始記錄日志了。。。最終");
        }
    }
}      

3.bean.xml

<?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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 配置spring建立容器時要掃描的包-->
    <context:component-scan base-package="com"></context:component-scan>

    <!-- 配置spring開啟注解AOP的支援 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>      

4測試

import com.service.IAccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AOPTest {
    public static void main(String[] args) {
        //1.擷取容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //2.擷取對象
        IAccountService as = (IAccountService)ac.getBean("accountService");
        //3.執行方法
        as.saveAccount();
    }
}      

5結果

spring基于 注解的 AOP 的前後置通知,異常通知,最終通知,環繞通知

6.順序問題

7.基本注解