前言
前面讲过IoC操作bean管理,这里主要对Spring的另一核心AoP做个描述。AoP:面向切面编程,它可以在不通过修改源代码的基础之上,在主干功能里增加新的功能。
一、AoP的特点及功能
1、特点:利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
2、主要功能:日志记录,性能统计,安全控制,事务处理,异常处理等等。
二、AoP的原理及JDK动态代理
1、aop底层用了动态代理,有两种情况的动态代理:
第一种 有接口的情况,使用JDK动态代理,创建接口实现类代理对象,增加类的方法。
第二种 没有接口的情况,使用CGLIB动态代理,创建当前类子类的代理对象,增加类的方法。
2、JDK动态代理
(1)使用JDK动态代理,使用Proxy类里面的方法创建代理对象
(2)调用newProxyInstance方法
方法里有三个参数:第一个参数表示类加载器。第二个参数表示增强方法所在的类,这个类实现的接口,支持多个接口。第三个参数表示实现接口InvocationHandler,创建代理对象,写增强的方法
三、基于注解的方式实现AoP
1、Aop的相关术语
(1)连接点
类里面哪些方法可以被增强,这些方法称为连接点
(2)切入点
实际被真正增强的方法,称为切入点
(3)通知(增强)
实际增强的逻辑部分称为通知(增强),比如登录功能中的权限判断
通知有多种类型,如下所示:
前置通知:@Before
后置通知:@AfterReturning(返回通知)
环绕通知:@Around
异常通知:@AfterThrowing
最终通知:@After(无论程序出不出现异常,其都会出现,且出现在被增强方法之后,所以称为最终通知)
(4)切面
把通知应用到切入点的过程,比如将权限判断加入进登录方法中
(5)切入点表达式
切入点表达式的作用:知道对哪个类里面的哪个方法进行增强。语法结构如下:
execution(【权限修饰符】【返回类型】【类全路径】【方法名称】(【参数列表】))
@Before(value = "execution(* com.aopanno.User.add(..))")
权限修饰符可以不写,但返回值必须要写,*表示任意返回类型,它必须要与类全路径名用空格隔开,add表示要增强的方法,“..”表示参数列表 。
2、导入相关依赖
Spring框架一般都是基于AspectJ实现AOP操作的。AspectJ不是Spring的组成部分,它是一个独立的AOP框架,一般把AspectJ和Spring框架一起使用,进行AOP操作。所以要导入AspectJ的jar包。
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies>