动态代理:
原理:使用一个代理将对象包装起来,然后用该对象取代原始对象,任何对原始对象的调用都要通过代理,代理对象决定是否以及何时讲方法调用转到原始对象上
动态代理:
1. 基于接口 -----JDK动态代理
2.基于继承 -----CGlib动态代理
类似微商,微商就是代理,他宣传买东西,你通过他买东西,但是真正买东西的还是卖家:
比如程序代码计算器,如果想增减日志代理、验证代理等,但是计算实现功能依然是【程序代码计算器】
//接口,目标类和代理类都实现同一个接口
public interface ArithmeticCalculator { int add(int a,int b); int sub(int a,int b); int mul(int a,int b); int div(int a,int b); }
public class ArithmeticCalculatorImpl implements ArithmeticCalculator { @Override public int add(int a, int b) { int result = a + b; return result; } @Override public int sub(int a, int b) { int result = a - b; return result; } @Override public int mul(int a, int b) { int result = a * b; return result; } @Override public int div(int a, int b) { int result = a / b; return result; } }
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * JDK的动态代理 * 1. Proxy:是所有动态类的父类,专门为用户生成代理类或者代理对象 * @CallerSensitive * public static Class<?> getProxyClass(ClassLoader loader, * Class<?>... interfaces) * 用于生成代理类的Class对象 * @CallerSensitive * public static Object newProxyInstance(ClassLoader loader, * Class<?>[] interfaces, * InvocationHandler h) * 用于生成代理类对象 * 2. InvocationHandler:完成动态代理的整个过程。 * public Object invoke(Object proxy, Method method, Object[] args) * throws Throwable; * */ public class ArithmeticCalculatorProxy { private Object target; public ArithmeticCalculatorProxy(Object target) { this.target = target; } public Object getProxy(){ Object proxy; /** * loader: ClassLoader对象,类加载器对象,帮我们加载动态生成的代理类 * interfaces:接口们,提供目标对象的所有接口,目的是让代理对象与目标对象都有接口中相同的方法 * InvocationHandler : 接口 */ ClassLoader classLoader = target.getClass().getClassLoader(); Class<?>[] interfaces = target.getClass().getInterfaces(); proxy = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() { /** * invoke: 代理对象调用代理方法,会回来调用invoke方法 * proxy:代理对象,在invoke方法中一般不会使用 * method:正在被调用的方法对象 * args: 正在被调用方法的参数 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //讲方法的调用转到目标对象上 //获取方法的名字 String methodName = method.getName(); //记录日志 System.out.println(" zhe method "+methodName+" begin"); Object result = method.invoke(target, args); System.out.println(" zhe method "+methodName+" end"); return result; } }); return proxy; } }
模拟动态代理底层实现
class $Proxy0 extends Proxy implements ArithmeticCalculator{ protected $Proxy0(InvocationHandler h) { super(h); } @Override public int add(int a, int b) { //return super.h.invoke(this,方法对象,方法参数); return 0; } @Override public int sub(int a, int b) { return 0; } @Override public int mul(int a, int b) { return 0; } @Override public int div(int a, int b) { return 0; } }
public class Demo { public static void main(String[] args)throws Exception { ArithmeticCalculatorImpl arithmeticCalculator = new ArithmeticCalculatorImpl(); Object proxy = new ArithmeticCalculatorProxy(arithmeticCalculator).getProxy(); /** * 第一步 : 生成代理类, * (1) proxy = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler().... * 通过这个方法生成代理对象, * * 第二步: 根据代理类生成代理对象 * Object proxy = new ArithmeticCalculatorProxy(arithmeticCalculator).getProxy(); * * 第三步:对象调用相应方法 proxy3.add(1, 1) * 第三步底层模拟如下 * class $Proxy0 extends Proxy implements ArithmeticCalculator{ * * protected $Proxy0(InvocationHandler h) { * super(h); * } * * @Override * public int add(int a, int b) { * 此处会调用此方法 super.h.invoke(this,方法对象,方法参数);它会调用 Invocation接口中的invoke方法 * public Object invoke(Object proxy, Method method, Object[] args) * throws Throwable; * //return super.h.invoke(this,方法对象,方法参数); * return 0; * } * * @Override * public int sub(int a, int b) { * return 0; * } * * @Override * public int mul(int a, int b) { * return 0; * } * * @Override * public int div(int a, int b) { * return 0; * } * } */ ArithmeticCalculator proxy3 =(ArithmeticCalculator)proxy; System.out.println(proxy3.add(1, 1)); } }
原文:https://www.cnblogs.com/lcj12121/p/11385989.html