1 > 前期准备
1.1 > pom文件依赖,SpringIOC配置,配置需扫描的包
<dependencies>
<!-- spring ioc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.9</version>
</dependency>
<!-- aop -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
1.2 > 项目结构图
1.3 > Logger(通知类Advice,切面类)
用与增强需要被增强的类
execution:表达式,对应execution括号中的内容
// 某个类下的某个方法
// @Pointcut("execution(public void com.xx01.dao.impl.AccountDaoImpl.saveAccount(Float))")
// 省略public修饰符
// @Pointcut("execution(void com.xx01.dao.impl.AccountDaoImpl.saveAccount(Float))")
// 省略void返回值 用 * 通配符代替 表示返回值为任意类型
// @Pointcut("execution(* com.xx01.dao.impl.AccountDaoImpl.saveAccount(Float))")
// 省略包名 此时*表示本层所有包(com一级)
// *.* :第二个*表示xx01本层所有的包
// @Pointcut("execution(* *.*.dao.impl.AccountDaoImpl.saveAccount(Float))")
// 表示本层级包下的所有子包
// @Pointcut("execution(* *..AccountDaoImpl.saveAccount(Float))")
// 表示本层级包下的所有子包,所有类下的所有方法,参数列表为任意类型
// @Pointcut("execution(* *..*.*(..))")
package com.xx01.advice;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component("logger") //用于springIOC容器进行扫描时,将本类存入IOC容器
@Aspect // 声明这是一个切面类
public class Logger {
// 表示本层级包下的所有子包,所有类下的所有方法,参数列表为任意类型
@Pointcut("execution(* *..*.*(..))")
private void pointcut(){
};
@Before("pointcut()")
public void beforeAdvice() {
// 前置通知
System.out.println("This is : " + Thread.currentThread().getStackTrace()[1].getMethodName());
}
@AfterReturning("pointcut()")
public void afterRunningAdvice() {
// 后置通知
System.out.println("This is : " + Thread.currentThread().getStackTrace()[1].getMethodName());
}
@AfterThrowing("pointcut()")
public void exceptionAdvice() {
// 异常通知
System.out.println("This is : " + Thread.currentThread().getStackTrace()[1].getMethodName());
}
@After("pointcut()")
public void afterAdvice() {
// 最终通知
System.out.println("This is : " + Thread.currentThread().getStackTrace()[1].getMethodName());
}
@Around("pointcut()")
public Object roundAdvice(ProceedingJoinPoint point) {
// 设置的返回对象
Object returnValue = null;
// 得到方法执行所需要的参数
Object[] args = point.getArgs();
try {
// 前置通知
System.out.println("This is : " + Thread.currentThread().getStackTrace()[1].getMethodName());
// 明确调用Dao层的方法
returnValue = point.proceed(args);
// 后置通知
afterRunningAdvice();
} catch (Throwable throwable) {
// 异常通知
exceptionAdvice();
throwable.printStackTrace();
}finally {
// 最终通知
afterAdvice();
}
return returnValue;
}
}
1.4 > AccountDao & AccountDaoImpl (接口及其实现类,实现类为被增强对象)
package com.xx01.dao;
public interface AccountDao {
// 无返回值有参数
void saveAccount(Float money);
// 有返回值 无参数
String findAllAccount();
// 有返回值 有参数
String findOneAccountById(Integer id);
}
// ---------------------------------------------
package com.xx01.dao.impl;
import com.xx01.dao.AccountDao;
import org.springframework.stereotype.Repository;
@Repository("accountDaoImpl")
public class AccountDaoImpl implements AccountDao {
@Override
public void saveAccount(Float money) {
System.out.println("Save money is : " + money);
}
@Override
public String findAllAccount() {
return "This findAllAccount !!";
}
@Override
public String findOneAccountById(Integer id) {
return "findOneAccountById method : Id is " + id;
}
}