1 > 前期准备
1.1 > pom文件依赖,SpringIOC配置,配置需扫描的包
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.9</version>
</dependency>
<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")
@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());
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;
}
}
1.5 > 测试(没有用Around环绕方法,注解方式配置通知会有顺序上的问题)
1.6 > 测试(Around环绕方法,注解方式配置则不会出现顺序上的问题)
|