目录
3.Advice,在切入点上执行的增强处理,主要有五个注解:
2. AspectTest类,使用execution()定义切点
3. AnnotationAspectTest类,使用注解定义切点
1. AOP基本概念:
AOP(Aspect Oriented Programming)是一种面向切面的编程思想。面向切面编程是将程序抽象成各个切面,即解剖对象的内部,将那些影响了多个类的公共行为抽取到一个可重用模块里,减少系统的重复代码,降低模块间的耦合度,增强代码的可操作性和可维护性。AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理、增强处理。
2. @Aspect的使用及其相关知识
1. 切面类
定义切面类,需添加两个注解, @Component、@Aspect注解。
@Component
@Aspect
@Slf4j
public class LogAspect {
}
2. 切点 @Pointcut
切点定义一般有两种方法,一种是自定义注解引用,另一种是使用execution()方法标示切点位置。
/**
* 定义切点,切点为对应controller
* 注:execution表达式第一个*表示匹配任意的方法返回值,第二个*表示所有controller包下的类,
* 第三个*表示所有方法,第一个..表示任意参数个数。
*/
@Pointcut("execution(public * com.example.zcs.Aop.controller.*.*(..))")
public void aopPointCut(){
}
/**
* 配置切入点
*/
@Pointcut("@annotation(com.iot.annotation.Log)")
public void logPointcut() {
// 该方法无方法体,主要为了让同类中其他方法使用此切入点
}
3.Advice,在切入点上执行的增强处理,主要有五个注解:
@Before 在切点方法之前执行
@After 在切点方法之后执行
@AfterReturning 切点方法返回后执行
@AfterThrowing 切点方法抛异常执行
@Around 属于环绕增强,能控制切点执行前,执行后
4.JoinPoint :
方法中的参数JoinPoint为连接点对象,它可以获取当前切入方法的参数,代理类等信息,因此可以记录和验证一些信息;
3. 具体代码实现
1. AopController 类,验证aop是否生效
@RestController
@RequestMapping("/aop")
public class AopController {
@RequestMapping("test")
public Result aopTest(User user) {
System.out.println("aop测试");
return Result.success();
}
@Log("测试aop注解")
@RequestMapping("/aopAnnotationTest")
public Result aopAnnotationTest(User user) {
System.out.println("aopAnnotationTest");
return Result.success();
}
}
2. AspectTest类,使用execution()定义切点
@Aspect
@Component
@Slf4j
public class AspectTest {
/**
* 定义切点,切点为对应controller
*/
@Pointcut("execution(public * com.example.zcs.Aop.controller.*.*(..))")
public void aopPointCut(){
}
@Before("aopPointCut()")
public void testbefor(JoinPoint joinPoint) {
System.out.println("执行方法之前执行。。。。。");
}
@After("aopPointCut()")
public void testAfter(JoinPoint joinPoint) {
System.out.println("执行方法之后执行。。。。。");
}
}
3. AnnotationAspectTest类,使用注解定义切点
@Aspect
@Component
@Slf4j
public class AnnotationAspectTest {
/**
* 定义切点,切点为添加了注解的方法
*/
@Pointcut("@annotation(com.Aop.annotation.Log)")
public void aopPointCut(){
}
@Around("aopPointCut()")
public Object Around(ProceedingJoinPoint point) throws Throwable {
System.out.println("AnnotationAspectTest Around start ");
//获取注解和注解的值
Log log = getAnnotation(point);
if (log != null) {
String logValue = log.value();
System.out.println("注解Log的值:" + logValue);
}
//获取参数
Object[] args = point.getArgs();
for (Object arg : args) {
System.out.println("arg ==>" + arg);
}
//去调用被拦截的方法
Object proceed = point.proceed();
return proceed;
}
// 获取注解的值
public Log getAnnotation(ProceedingJoinPoint point) {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
if (method != null){
return method.getAnnotation(Log.class);
}
return null;
}
}
4. @Log注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
String value() default "";
/**
* 是否启用
*
* @return
*/
boolean enable() default true;
LogActionType type() default LogActionType.SELECT;
}