java-spring aop
导读
- AOP 面向切面编程 Aspect oriented Programming
- OOP 面向对象编程 Object oriented Programming
- 作用:在不惊动原始设计的基础上进行功能增强。
- 切入点表达式可以是接口,也可以是实现类
1、导入坐标
<!-- aop面向切面 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.19</version>
<scope>runtime</scope>
</dependency>
2、在SpringConfig上开启@EnableAspectJAutoProxy
@Configuration
@ComponentScan("cn.tjhis")
@PropertySource({"classpath:druid.properties"})
@Import({DbConfig.class,MybatisConfig.class})
@EnableAspectJAutoProxy
public class SpringConfig {
}
3、开发切面
- 前提:只有在执行
ProductInfoService
的save
方法时,会触发。
@Component
@Aspect
public class MyAdvice {
@Pointcut("execution(void cn.tjhis.service.ProductInfoService.save())")
private void execute(){};
@Before("execute()")
public void method(){
System.out.println(LocalDateTime.now());
}
}
// 任意返回值,任意包下 任意参数 以Service结尾的子类
@Pointcut("execution(* *..*Service+.*(..))")
private void execute(){};
@Before("execute()")
public void method(){
System.out.println(LocalDateTime.now());
}
- 通过
service.getClass()
可以看到被代理的那个对象
切入点通知类型
@Component
@Aspect
public class MyAdvice {
// 任意返回值,任意包下 任意参数 以Service结尾的子类
@Pointcut("execution(* *..*Service+.save(..))")
private void execute() {
}
;
/**
* 前置通知
*/
@Before("execute()")
public void before() {
System.out.println(LocalDateTime.now());
}
/**
* 后置通知
*/
@After("execute()")
public void after() {
System.out.println(LocalDateTime.now());
}
/**
* 如果同时存在 执行顺序为 此方法before -> 前置通知 -> afterReturning -> 后置通知 -> 此方法after
*
* @param joinPoint 切入点
* @throws Throwable 异常
*/
@Around("execute()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 显示调用的类名和方法名
Signature signature = joinPoint.getSignature();
// 方法名
String methodName = signature.getName();
// 类
Class<?> cls = signature.getDeclaringType();
// 类名
String className = signature.getDeclaringTypeName();
System.out.println(className + " " + methodName );
System.out.println("before:" + LocalDateTime.now());
// 执行原始方法
Object obj = joinPoint.proceed();
System.out.println("after:" + LocalDateTime.now());
return obj;
}
/**
* 返回后
*/
@AfterReturning("execute()")
public void afterReturning() {
System.out.println("afterReturning:" + LocalDateTime.now());
}
/**
* 异常
*/
@AfterThrowing("execute()")
public void afterThrowing() {
System.out.println("afterThrowing:" + LocalDateTime.now());
}
}
Around 是重点
@Component
@Aspect
public class MyAdvice {
// 任意返回值,任意包下 任意参数 以Service结尾的子类
@Pointcut("execution(* *..*Service+.save(..))")
private void execute() {
}
;
/**
* 前置通知
*/
@Before("execute()")
public void before(JoinPoint point) {
System.out.println("前置通知参数"+ Arrays.toString(point.getArgs()));
System.out.println(LocalDateTime.now());
}
/**
* 后置通知
*/
@After("execute()")
public void after() {
System.out.println(LocalDateTime.now());
}
/**
* 如果同时存在 执行顺序为 此方法before -> 前置通知 -> afterReturning -> 后置通知 -> 此方法after
* @param point 切入点
* @throws Throwable 异常
*/
@Around("execute()")
public Object around(ProceedingJoinPoint point) {
System.out.println("环绕参数"+ Arrays.toString(point.getArgs()));
// 显示调用的类名和方法名
Signature signature = point.getSignature();
// 方法名
String methodName = signature.getName();
// 类
Class<?> cls = signature.getDeclaringType();
// 类名
String className = signature.getDeclaringTypeName();
System.out.println(className + " " + methodName );
System.out.println("before:" + LocalDateTime.now());
// 执行原始方法
Object obj = null;
try {
obj = point.proceed();
} catch (Throwable e) {
System.out.println(e.getMessage());
}
System.out.println("after:" + LocalDateTime.now());
return obj;
}
/**
* 返回后
*/
@AfterReturning(value = "execute()",returning = "ret")
public void afterReturning(Object ret) {
System.out.println("afterReturning:" + LocalDateTime.now() + " 返回值:" + ret);
}
/**
* 异常
*/
@AfterThrowing(value = "execute()",throwing = "e")
public void afterThrowing(Throwable e) {
System.out.println("afterThrowing:" + LocalDateTime.now() + " 异常:" + e.getMessage());
}
}
- 若参数中含有空格,去除空格 记得参数修改后必须再传回去
@Around("execute()")
public Object around(ProceedingJoinPoint point) {
Object[] args = point.getArgs();
for (int i = 0; i < args.length; i++) {
if (Objects.equals(args[i].getClass(),String.class)){
args[i] = args[i].toString().trim();
}
}
return point.proceed(args);
}
世界上没有什么事情是跑步解决不了的,如果有,那就再跑一会!