天天看點

【Spring】基礎入門篇(十) 基于注解的SpringAOP配置 Spring·基礎入門篇(十) 基于注解的SpringAOP配置

Spring·基礎入門篇(十) 基于注解的SpringAOP配置

1. 環境搭建

基于注解方式配置AOP實作日志系統為案例

第一步:建立普通Maven工程

第二步:導入pom.xml坐标

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>
<dependency>
     <groupId>org.aspectj</groupId>
     <artifactId>aspectjweaver</artifactId>
     <version>1.8.7</version>
 </dependency>
           

第三步::在配置檔案中導入 context 的名稱空間

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 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">
</beans>
           
此處要導入 aop 的限制

第四步:把資源使用注解配置

/**
 * @author: LzCc
 * @blog: https://blog.csdn.net/qq_41744145
 * @description: 賬戶的業務層接口
 */
public interface IAccountService {
    /**
     * 模拟儲存賬戶
     */
   void saveAccount();
    /**
     * 模拟更新賬戶
     * @param i
     */
   void updateAccount(int i);
    /**
     * 删除賬戶
     * @return
     */
   int  deleteAccount();
}
/**
 * @author: LzCc
 * @blog: https://blog.csdn.net/qq_41744145
 * @description: 賬戶的業務層實作類
 */
@Service("accountService")
public class AccountServiceImpl implements IAccountService{
    @Override
    public void saveAccount() {
        System.out.println("執行了儲存");
    }
    @Override
    public void updateAccount(int i) {
        System.out.println("執行了更新"+i);

    }
    @Override
    public int deleteAccount() {
        System.out.println("執行了删除");
        return 0;
    }
}
           

第五步:抽取公共代碼制作成通知

/**
 * @author: LzCc
 * @blog: https://blog.csdn.net/qq_41744145
 * @description: 用于記錄日志的工具類,它裡面提供了公共的代碼
 */
@Component("logger")
public class Logger {
    /**
     * 前置通知
     */
    public  void beforePrintLog(){
        System.out.println("前置通知Logger類中的beforePrintLog方法開始記錄日志了。。。");
    }
    /**
     * 後置通知
     */
    public  void afterReturningPrintLog(){
        System.out.println("後置通知Logger類中的afterReturningPrintLog方法開始記錄日志了。。。");
    }
    /**
     * 異常通知
     */
    public  void afterThrowingPrintLog(){
        System.out.println("異常通知Logger類中的afterThrowingPrintLog方法開始記錄日志了。。。");
    }
    /**
     * 最終通知
     */
    public  void afterPrintLog(){
        System.out.println("最終通知Logger類中的afterPrintLog方法開始記錄日志了。。。");
    }
           

第六步:在配置檔案中指定 spring 要掃描的包

<!-- 告知 spring,在建立容器時要掃描的包 -->
<context:component-scan base-package="top.lzchao"></context:component-scan>
           

2. 配置AOP

2.1 第一步:在通知類上使用@Aspect 注解聲明為切面

@Aspect : 把目前類聲明為切面類。

/**
 * @author: LzCc
 * @blog: https://blog.csdn.net/qq_41744145
 * @description: 用于記錄日志的工具類,它裡面提供了公共的代碼
 */
@Component("logger")
@Aspect//表示目前類是一個切面類
public class Logger { ... }
           

2.2 第二步:在增強的方法上使用注解配置通知

@Before:把目前方法看成是前置通知。

@AfterReturning:把目前方法看成是後置通知

@AfterThrowing:把目前方法看成是異常通知。

@After:把目前方法看成是最終通知。

  • 屬性:

    value:用于指定切入點表達式,還可以指定切入點表達式的引用

/**
 * 前置通知
 */
@Before("execution(* top.lzchao.service.impl.*.*(..))")
public  void beforePrintLog(){
    System.out.println("前置通知Logger類中的beforePrintLog方法開始記錄日志了。。。");
}
/**
 * 後置通知
 */
@AfterReturning("execution(* top.lzchao.service.impl.*.*(..))")
public  void afterReturningPrintLog(){
    System.out.println("後置通知Logger類中的afterReturningPrintLog方法開始記錄日志了。。。");
}
/**
 * 異常通知
 */
@AfterThrowing()
public  void afterThrowingPrintLog(){
    System.out.println("異常通知Logger類中的afterThrowingPrintLog方法開始記錄日志了。。。");
}
/**
 * 最終通知
 */
@After("execution(* top.lzchao.service.impl.*.*(..))")
public  void afterPrintLog(){
    System.out.println("最終通知Logger類中的afterPrintLog方法開始記錄日志了。。。");
}
           

2.3 第三步:在 spring 配置檔案中開啟 spring 對注解 AOP 的支援

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

2.4 環繞通知注解配置

@Around:把目前方法看成是環繞通知。

  • 屬性:

    value:用于指定切入點表達式,還可以指定切入點表達式的引用。

/**
 * 環繞通知
 * @param pjp
 * @return
 */
@Around("execution(* top.lzchao.service.impl.*.*(..))")
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方法開始記錄日志了。。。最終");
    }
}
           

2.5 切入點表達式注解

@Pointcut:指定切入點表達式

  • 屬性:

    value:指定表達式的内容

@Pointcut("execution(* top.lzchao.service.impl.*.*(..))")
private void pt1() {}
/**
 * 環繞通知
 * @param pjp
 * @return
 */
@Around("pt1()")
public Object aroundPringLog(ProceedingJoinPoint pjp){ ... }
           

3. 純注解的方式

@EnableAspectJAutoProxy:開啟 spring 對注解 AOP 的支援

/**
 * @author: LzCc
 * @blog: https://blog.csdn.net/qq_41744145
 * @description: Spring配置類
 */
@Configuration
@ComponentScan(basePackages="top.lzchao")
@EnableAspectJAutoProxy
public class SpringConfiguration {
}