AOP-五种通知类型
前话:由于网不好大概,导致maven下载依赖很慢且出现问题:导致pom中显示正确且代码导包正常--》但一运行就出错,这让我找了半天的错误 最后我还是手动导包了~ 不然早弄完了 靠
目录:
Action.java
package org.javaboy.aop;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author 邓雪松 (づ ̄ 3 ̄)づ)
* @create 2021-10-26-19-39
* 这是一个自定义注解
* 注解的使用范围是:放在method上面
* 保留到运行的时候还存在
* 哪个方法上面有Action注解就在哪个方法上增强功能
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Action {
}
JavaConfig.java
package org.javaboy.aop;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* @author 邓雪松 (づ ̄ 3 ̄)づ)
* @create 2021-10-26-20-07
*/
@Configuration
@ComponentScan
//开启自动代理
@EnableAspectJAutoProxy
public class JavaConfig {
}
LogAspect.java
package org.javaboy.aop;
import org.aopalliance.intercept.Joinpoint;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* @author 邓雪松 (づ ̄ 3 ̄)づ)
* @create 2021-10-26-19-45
* @Component:代表这是个组件
* @Aspect:表示这是一个切面
*/
@Component
@Aspect
public class LogAspect {
/**
* 前置通知 再目标方法执行之前执行
* @param joinPoint
* 就是执行add()方法之前这个方法会打印懂?
*/
@Before("@annotation(Action)")
public void before(JoinPoint joinPoint){
String name = joinPoint.getSignature().getName();
System.out.println(name+"方法开始执行了~");
}
/**
* 后置通知,在目标方法执行之后执行
* @param joinPoint
*/
@After("@annotation(Action)")
public void after(JoinPoint joinPoint){
String name = joinPoint.getSignature().getName();
System.out.println(name+"方法执行结束了...a");
}
/**
* 返回通知,可以在该方法中获取目标方法的返回值,如果目标方法的返回值为void,则收到null
* @param joinPoint
* @param r 返回的参数名称 和这里方法的参数名一一对应
*/
@AfterReturning(value = "@annotation(Action)",returning = "r")
public void returning(JoinPoint joinPoint,Integer r){
String name = joinPoint.getSignature().getName();
System.out.println(name+"方法返回通知:"+r);
}
/**
* 异常通知,当目标方法抛出异常时,该方法会触发
* @param joinPoint
* @param e 异常参数,和方法的参数名一一对应,注意异常的类型
*/
@AfterThrowing(value = "@annotation(Action)",throwing = "e")
public void afterThrowing(JoinPoint joinPoint,Exception e){
String name = joinPoint.getSignature().getName();
System.out.println(name+"方法异常通知:"+e.getMessage());
}
/**
* 环绕通知,环绕通知是上面四种方法的集大成者,环绕通知的核心类似于在反射中执行方法
* @param pjp
* @return
*/
@Around("@annotation(Action)")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
//这个方法有点类似于method.invoke 方法,我们可以在这个方法的前后分别添加日志,相当于前置/后置通知
Object proceed = pjp.proceed(new Object[]{5,5});
return proceed;
}
}
Main.java
package org.javaboy.aop;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @author 邓雪松 (づ ̄ 3 ̄)づ)
* @create 2021-10-26-20-07
*/
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(JavaConfig.class);
MyCalculator calculator = ctx.getBean(MyCalculator.class);
calculator.add(3,4);
calculator.min(3,4);
}
}
MyCalculator.java
package org.javaboy.aop;
/**
* @author 邓雪松 (づ ̄ 3 ̄)づ)
* @create 2021-10-26-19-30
*/
public interface MyCalculator {
int add(int a,int b);
void min(int a,int b);
}
MyCalculatorImpl.java
package org.javaboy.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.springframework.stereotype.Component;
/**
* @author 邓雪松 (づ ̄ 3 ̄)づ)
* @create 2021-10-26-19-32
*/
@Component
public class MyCalculatorImpl implements MyCalculator {
@Action
public int add(int a, int b) {
// int x = 1/0;
System.out.println(a + "+" + b + "=" + (a+b));
return a + b;
}
@Action
public void min(int a, int b) {
System.out.println(a + "-" + b + "=" + (a-b));
}
}
运行结果如下
add方法开始执行了~
5+5=10
add方法返回通知:10
add方法执行结束了...a
min方法开始执行了~
5-5=0
min方法执行结束了...a
完 ~