1、基本概念
- (1)面向切面编程(方面),利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
- (2)通俗描述:不通过修改源代码方式,在主干功能里面添加新功能
比如说、你完成了一个功能需求、后来产品经理在这个需求上增加一些新需求。你要么修改源代码(这个可能比较麻烦、耦合性也高)、这个时候就可以使用AOP切面编程、对原有的需求进行功能增强。横切进去、就可以在不修改原先代码的基础上、完成新的需求(也方便后期维护、万一产品经理说、这样又不好呢。修改起来也容易、直接将切面拿走。)
- (3)使用登录例子说明 AOP
2、底层原理
AOP 底层使用动态代理
有两种情况动态代理
- 第一种 有接口情况,使用 JDK 动态代理
创建接口实现类代理对象,增强类的方法
- 第二种 没有接口情况,使用 CGLIB 动态代理
创建子类的代理对象,增强类的方法
3、JDK动态代理实现
3.1 查看对应Proxy方法使用
1、使用 JDK 动态代理,使用 Proxy 类里面的方法创建代理对象
开胃小知识
3.2 方法详解
(1)调用 newProxyInstance 方法
方法有三个参数:
第一参数,类加载器
第二参数,增强方法所在的类,这个类实现的接口,支持多个接口
第三参数,实现这个接口 InvocationHandler,创建代理对象,写增强的部分
3.3 JDK动态代理代码
3.3.1 创建接口,定义方法
PersonDao .java
/**
* @author Lenovo
* @version 1.0
* @data 2022/10/19 22:37
*/
public interface PersonDao {
public int add(int a,int b);
public void update(int a);
}
3.3.2 创建接口实现类,实现方法
PersonDaoImpl.java
/**
* @author Lenovo
* @version 1.0
* @data 2022/10/19 22:39
*/
public class PersonDaoImpl implements PersonDao {
@Override
public int add(int a, int b) {
System.out.println("执行了add方法");
return a+b;
}
@Override
public void update(int a) {
System.out.println(a);
}
}
3.3.3 使用 Proxy 类创建接口代理对象
/**
* @author Lenovo
* @version 1.0
* @data 2022/10/19 22:40
*/
public class JdkProxy {
public static void main(String[] args) {
//创建接口实现类代理对象
Class[] interfaces = {PersonDao.class};
// Proxy.newProxyInstance(JdkProxy.class.getClassLoader(), interfaces,
// new InvocationHandler() {
// @Override
// public Object invoke(Object proxy, Method method, Object[] args)
// throws
// Throwable {
// return null;
// }
// });
PersonDaoImpl personDao = new PersonDaoImpl();
PersonDao dao = (PersonDao) Proxy.newProxyInstance(JdkProxy.class.getClassLoader(), interfaces, new PersonDaoProxy(personDao));
int rs = dao.add(4, 5);
System.out.println("result:" + rs);
}
}
/**
* 代理对象代码
*/
class PersonDaoProxy implements InvocationHandler {
/**
* 1 把创建的是谁的代理对象,把谁传递过来
* 有参数构造传递
*/
private Object obj;
public PersonDaoProxy(Object obj) {
this.obj = obj;
}
/**
* 增强的逻辑
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//方法之前
System.out.println("方法执行之前:" + method.getName() + ",传递的参数是:" + Arrays.toString(args));
//被增强的方法执行
Object rs = method.invoke(obj, args);
//方法之后
System.out.println("方法执行之后:" + obj);
return rs;
}
}
3.3.4 测试结果
4、后语
学无止境…