1.Aop的定义
AOP(面向切面编程)是一种编程范式,旨在通过将横切关注点(如日志记录、性能监控、事务管理等)从业务逻辑中分离出来,以提高代码的模块化和可维护性。我自己的理解就是,在不改变原始代码的前提下,追加代码的功能。
原始代码里的所有方法都称为“连接点”,所要追加新功能的方法称为“切入点”, 所追加的新功能称为“通知”,有了“通知”和“切入点”,就要进行两个之间的绑定,这个绑定称为“切面”,“通知”和“切入点”的绑定是多对多的关系,一个通知可以连接多个切入点,一个切入点也可以连接多个通知
2.引入Aop的坐标
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
3.定义Aop的通知类
在该类的上方加上两个注解,@Component 把该类管理到容器中,@Aspect 说明该类是通知类
同时,spring的配置类上方还要加上@EnableAspectJAutoProxy注解,该注解可以说是用来扫描通知类的,与通知类的@Aspect注解相对应
4.定义切入点
假设在Dao接口中有几个方法,在接口的实现类中分别实现了这些方法,现在要为某个方法追加新的功能,但是又不能改变实现类中方法的代码,这就引入的Aop的作用
在所定义的Aop通知类里面定义切入点,目的是要明确哪些方法要追加新功能
4.1.定义对照切入点的方法
在通知类中定义一个方法,该方法无参数,也没有内容,该方法是要对应切入点,在方法的上方加上@Pointcut注解,表示这是连接切入点的方法,在注解的括号里,加上切入点的路径,”execution"表示执行,要执行该路径,在路径的前面有一个“void”,这表示切入点的类型,现在在通知类中就定义好了一个方法表示切入点。
4.2.切入点路径的表示
除了上述所定义的切入点的绝对路径以外,还有一种简单的方法,可以一次性定义多个切入点的路径。
使用 * 号和 ".." 两个点,* 号代表一个或多个, ".." 代表没有或多个
举个例子
把之前的绝对路径改变一下,把里面的一些类和包改成了 * 号,第一个 * 号表示切入点的类型,意思是可以是任意类型,第二个 * 号表示包,意思是可以是com.example.spring_aop这个包下面的任意包,第三个 * 号表示接口或者实现类,意思是任意的接口或者实现类下面的select()方法,当然,方法也可以用 * 号表示,意思是任意接口或者实现类下面的任意方法,而select()方法里面的参数用 .. 表示,意思是可以没有参数或者多个参数。
改成这种形式的路径之后,程序会根据所定义的路径,去匹配你的包,接口或者实现类,最后匹配方法,这种路径方式可以一次性的匹配到多个切入点,简化的开发过程,在实际开发中也是非常常用的方式
5.定义通知方法
通知方法有很多类型,最主要的有三个类型,分别是前置通知,后置通知,环绕通知,其中环绕通知是开发中最常用的,也是最重要的,环绕通知可以包含前置通知和后置通知
在通知类中定义一个通知方法,该方法的内部内容就是对切入点所追加的新功能
5.1.前置通知
在通知方法的上方加上@Before注解,注解后面加上之前定义的对照切入点的方法,该注解的意思是在执行切入点之前,先执行通知方法,这样就实现了把新功能加到了切入点的前面
5.2.后置通知
同理可得,后置通知是把追加的新功能放在切入点的后面执行
5.3.环绕通知
5.3.1.无返回值的环绕
环绕通知最大的特点就是需要调用原始方法,原始方法就是切入点,通知方法的括号里的参数是生成一个对象,在下面用proceed() 方法调用原始方法,所以,pjp.proceed() 就代表原始方法的执行,而所追加的新功能写在pjp.proceed() 的上方就是前置通知,写在下方就是后置通知
环绕通知还要抛出异常,因为在环绕通知方法里面调用了原始方法,不确定原始方法中是否存在异常,所要环绕通知要进行抛异常处理
5.3.2.有返回值的环绕
如果原始方法是一个有返回值的方法,则需要在通知方法里面把返回值进行返回,同时,通知方法的类型也要改成Object 类型
定义一个参数接收原始方法的返回值,然后在通知方法里再返回出去
6.获取切入点的信息
在环绕通知方法里面,用 pjp 对象,调用 getSignature() 方法,可以获得有关原始方法的一切信息,包括原始方法的类型,名字等等,把所有的信息封装到定义的对象 signature 里面,然后再通过该对象的具体方法取出对应的信息
如果原始方法含有参数,可以用 pjp.getArgs() 方法获得原始方法是参数,参数以数组类型获取