Spring AOP
1-AOP动态代理(JDK实现)
2021-08-14 96 1
简介 AOP到底是什么? JDK中的Proxy实现动态代理
1. AOP
什么是 AOP
(1)面向切面编程(方面), 利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
(2)通俗描述:不通过修改源代码方式,在主干功能里面添加新功能,
这里的“不通过修改源代码”需要深入说明以下,通俗来说,就是不对原来的代码进行修改,再次强调,是修改, 但是可以增加配置、增加代码。
这也就是面向对象开发的基本原则“开闭原则”的具体体系, 对扩展开放,对修改封闭。
2. AOP的实现-通过JDK中的Proxy类
1. 被代理类接口
public interface OrderDao {
public int add(int i);
}
2. 被代理类
public class OrderDaoImpl implements OrderDao{
@Override
public int add( int i ) {
System.out.println("add order ...");
return i;
}
}
3. 代理类
//创建代理类
class OrderDaoProxy implements InvocationHandler{
// 需要代理谁? 把谁传过来 -- 通过构造器构造, obj就是代理对象
Object obj;
public OrderDaoProxy(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//1. 代理对象功能增强逻辑(执行前)
System.out.println("#1. exec " + method.getName() + " before ... ");
//2. 被代理对象的执行逻辑
// 返回值 invoke 就是被代理对象执行的方法的返回值
Object invoke = method.invoke(obj, args);
//3. 代理对象功能增强逻辑(执行后)
System.out.println("#2. exec " + method.getName() + " after ... ");
return invoke;
}
}
4. 运行类
public class ProxyMainDemo {
public static void main(String[] args) {
// 代理对象需要实现的接口 可以多个,是数组形式
Class[] interfaces = {OrderDao.class};
//被代理对象
OrderDao orderDao = new OrderDaoImpl();
//Object obj = Proxy.newProxyInstance(OrderProxy.class.getClassLoader(), interfaces, new OrderDaoProxy(orderDao));
OrderDao obj = (OrderDao) Proxy.newProxyInstance(ProxyMainDemo.class.getClassLoader(), interfaces, new OrderDaoProxy(orderDao));
int add = obj.add(10); // 通过反射, newInstance获得代理类对象
System.out.println(add);
//返回的 obj 到底是个啥? ---- class com.sun.proxy.$Proxy0 getProxyClass0获得
System.out.println(obj.getClass());
//返回的 obj 是哪些接口的实现类的对象? --- interface com.ylaihui.spring5.aop.OrderDao
Class<?>[] interfaces1 = obj.getClass().getInterfaces();
for (Class<?> aClass : interfaces1) {
System.out.println(aClass);
}
// 代理类中有没有 被代理类的 add 方法 ? 还有什么方法? ---- add equals toString hashCode
Method[] declaredMethods = obj.getClass().getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod.getName());
}
}
}
运行结果:
#1. exec add before ...
add order ...
#2. exec add after ...
10
class com.sun.proxy.$Proxy0
interface com.ylaihui.spring5.aop.OrderDao
add
equals
toString
hashCode
运行类的时序图