AOP
概念
-
什么是AOP?
它是“面向切面编程”的缩写,或者说“面向方面编程”
软件里有各个功能(业务逻辑),把它们分离开来,可以降低耦合度,提高程序的可重用性。
举个例子:
我们想做一个最基本的登录功能,做好后我想在登录功能的基础上添加(完善)功能:权限判断(管理员用户、普通用户…)
-
原视方式:修改源代码实现
-
现在:不通过修改源代码方式,在原有基础之上添加新的功能。(美国宪法)
可以把独立出一个权限判断新模块,给它配置到主干里区。
这样大大降低了耦合度,某天不用到这个判断,只需要去掉这个模块。
底层原理
AOP是怎么实现的呢?
-
AOP底层使用动态代理的方式实现
有两种情况的动态代理:
-
有接口情况
使用JDK动态代理
- 🔺创建接口实现类代理对象,增强类的方法。
-
没有接口情况
使用CGLIB动态代理
- 创建当前类子类代理对象,同样不是new出来的。
-
通过代理对象,把要增加的功能做到。
动态代理:
有接口情况
有接口就有实现类,现在想要在登录基础之上加个新功能(判断),这就叫增强一个类中的方法
如何用AOP方式实现呢?这就需要JDK动态代理实现。
需要再创建一个接口实现类的代理对象,但不是new出来的。而是代理对象。
有它之前的功能,但与new出来对象是不一样的,他是代理对象。
没有接口情况
比如我想增强User类中的方法,以前我们是创建User类的子类,继承父类。(原视方式)但现在我们要通过动态代理做到:CGLIB动态代理。
要创建当前类子类的代理对象,同样不是new出来的。
通过代码,写一下JDK动态代理代码编写,加深印象。Spring5已经帮我们封装好了。
使用JDK动态代理
使用Proxy类里面的方法,来创建出代理对象。
java.lang(工具类).reflect包下有类叫Proxy类,其提供的方法能帮我们创建出代理对象。
返回指定接口的代理类的实例(对象)。
newProxyInstance
方法,里面有三个参数:
-
ClassLoader
类加载器 -
我们针对的是有接口情况,所以我们写接口的class。
即增强方法所在的类的这个类实现的接口;支持多个接口,所以返回Class类型的数组形式。
-
最重要
InvocationHandler
写增强的部分:它单独是一个接口!实现这个接口,创建代理对象,写增强的方法
但这里返回的是InvocationHandler h
实例对象(即我们创建的代理对象),返回指定接口的代理类的实例。(两种方法:1.直接创建匿名内部类,生成对象;2.创建一个InvocationHandler
接口的实现类,new它的实例对象。
现在我们来写一下吧~
基本背景:
-
创建接口,定义方法。
别忘了接口里的方法都是抽象方法,没有方法体的。
-
创建接口的实现类,实现方法
下面重点:增强功能
- 使用Proxy类创建接口代理对象
增强接口有多种写法:
- 写个匿名内部类,直接new
public class JDKProxy {
public static void main(String[] args) {
//用newProxyInstance方法创建接口实现类代理对象
//1.类加载器;2.要实现的接口(需要数组类型)
//3.增强接口
Class[] interfaces = {
UserDao.class};
Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return null;
}
});
}
}
- 单独写个类来实现接口
public class JDKProxy {
public static void main(String[] args) {
//用newProxyInstance方法创建接口实现类代理对象
//1.类加载器;2.要实现的接口(需要数组类型)
//3.增强接口
Class[] interfaces = {
UserDao.class};
Proxy.newPr