Spring5深入浅出篇:基于注解实现的AOP
基于注解的AOP编程的开发步骤
- 原始对象
- 额外功能
- 切⼊点
- 组装切⾯
代码语言:java复制可以发现其实1,2,3最终目的就是为了去组装切面,其实这里和我们传统开发aop的步骤是一样的
# 通过切⾯类 定义了 额外功能 @Around
定义了 切⼊点 @Around("execution(* login(..))")
@Aspect 切⾯类
package com.baizhiedu.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
/*
传统使用配置文件开发aop步骤
1. 额外功能
public class MyArround implements MethodInterceptor{
public Object invoke(MethodInvocation invocation){
Object ret = invocation.proceed();
return ret;
}
}
2. 切⼊点
<aop:config
<aop:pointcut id="" expression="execution(*login(..))"/>
*/
@Aspect
public class MyAspect {
//这里通过注解的方式定义切入点表达式
@Around("execution(* login(..))")
public Object arround(ProceedingJoinPoint joinPoint) throws
Throwable {
//增强额外方法,这里还是通过日志的形式表现
System.out.println("----aspect log ------");
//这里不再通过MethodInvocation的方式来代表原始方法执行,而是ProceedingJoinPoint
Object ret = joinPoint.proceed();
return ret;
}
}
代码语言:xml复制<bean id="userService"
class="com.baizhiedu.aspect.UserServiceImpl"/>
<!--
切⾯
1. 额外功能
2. 切⼊点
3. 组装切⾯
-->
<bean id="arround" class="com.baizhiedu.aspect.MyAspect"/>
<!--告知Spring基于注解进⾏AOP编程-->
<aop:aspectj-autoproxy />
细节
切⼊点复⽤
首先第一个问题,为什么需要切入点复用呢?主要是为了在同一个切入点增加一个额外方法,比如我们给切入点添加了日志方法还需要添加事务相关方法时,就需要重复编码导致代码可维护性差
首先看如下代码
代码语言:java复制@Aspect
public class MyAspect {
//这里通过注解的方式定义切入点表达式
@Around("execution(* login(..))")
public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {
//增强额外方法,这里还是通过日志的形式表现
System.out.println("----aspect log ------");
//这里不再通过MethodInvocation的方式来代表原始方法执行,而是ProceedingJoinPoint
Object ret = joinPoint.proceed();
return ret;
}
//可以明显发现这里写了重复的代码,如果我们需要将login方法替换成register方法将会需要修改每一个
@Around("execution(* login(..))")
public Object arround1(ProceedingJoinPoint joinPoint) throws Throwable {
//增强额外方法,这里还是通过日志的形式表现
System.out.println("----事务相关操作 ------");
//这里不再通过MethodInvocation的方式来代表原始方法执行,而是ProceedingJoinPoint
Object ret = joinPoint.proceed();
return ret;
}
}
通过切入点注解 @Pointcut 进行优化
代码语言:java复制切⼊点复⽤:在切⾯类中定义⼀个函数 上⾯@Pointcut注解 通过这种⽅式,定义切
⼊点表达式,后续更加有利于切⼊点复⽤。
@Aspect
public class MyAspect {
@Pointcut("execution(* login(..))")
public void myPointcut(){}
@Around(value="myPointcut()")
public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("----aspect log ------");
Object ret = joinPoint.proceed();
return ret;
}
@Around(value="myPointcut()")
public Object arround1(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("----aspect tx ------");
Object ret = joinPoint.proceed();
return ret;
}
}
动态代理的创建⽅式
代码语言:txt复制AOP底层实现 2种代理创建⽅式
1. JDK 通过实现接⼝ 做新的实现类⽅式 创建代理对象
2. Cglib通过继承⽗类 做新的⼦类 创建代理对象
默认情况 AOP编程 底层应⽤JDK动态代理创建⽅式
如果切换Cglib
1. 基于注解AOP开发
<aop:aspectj-autoproxy proxy-target-class="true" />
2. 传统的AOP开发
<aop:config proxy-target-class="true">
</aop>
AOP阶段知识总结
以上便是本文的全部内容,我是全干程序员demo,每天为你带来最新好用的开发运维工具,如果你觉得用,请点赞,让更多的人了解相关工具
如果你想了解更多关于全干程序员demo,可以关注公众号-全干程序员demo,后面文章会首先同步至公众号