动态代理的两种模式
- jdk动态代理 //基于实现接口
 - Cglib动态代理 //基于方法的继承
 
????????啥东西
这就不得不提到 静态代理了: 说得高大上,其实就是写一个增强类继承被增强类,
实现被增强类的同时,也可以在其中添加一些代码,增强了被增强类
但问题是:静态代理想要再增强,无非就是修改代码;或者再写一个类去增强那个增强类。
在实际开发中,这是一种很蠢的行为;跟套娃一样不说,代码冗余还越来越多。
动态代理
Spring提供了完美的动态代理,我们来看看其原理:
代码:jdk动态代理 :针对实现接口的类进行增强
public interface Subject { //公共接口
    void buyHouse();
} 
public class RealSubject implements Subject{
    @Override
    public void buyHouse() {
        System.out.println("买房子");
    }
} 
买房接口和买家买房实现类
jdk动态代理类:
public class JDKProxyFactory { //jdk动态代理工厂
    public static Object getProxyObj(Object obj){ //目标对象
        /**
         * ClassLoader loader,       类加载
         * Class<?>[] interfaces,    目标对象实现接口
         * InvocationHandler h       调用拦截器
         */
        //获取类加载器
        ClassLoader loader = obj.getClass().getClassLoader();
        //获取目标对象实现的接口
        Class<?>[] interfaces = obj.getClass().getInterfaces();
        //定义调用拦截器
        InvocationHandler handler = new InvocationHandler() {
            //当目标对象的方法调用的时候会回调这个方法
            /**
             *
             * @param proxy     代理对象
             * @param method    目标对象的方法
             * @param args      目标对象的参数
             * @return
             * @throws Throwable
             */
            @Override
public Object invoke(Object proxy, Method method, Object[] args)
 throws Throwable {
                System.out.println("找房源....");
                //调用目标对象的方法!!!!
                //参数1:类的对象  参数2:方法的参数
                Object invoke = method.invoke(obj, args);
                System.out.println("办理手续....");
                return invoke;  //这里的返回值就是目标对象的返回值
            }
        };
Object proxyObj = Proxy.newProxyInstance(loader, interfaces, handler);
        return proxyObj;
    } 
 
测试类:
public class JDKProxyTest {
    @Test
    public void test01(){
        //创建目标对象
        Subject realSubject = new RealSubject();
        //realSubject.buyHouse();
        //通过代理工厂创建代理对象
        Subject proxyObj = (Subject) JDKProxyFactory.getProxyObj(realSubject);
        //把方法传给代理类
        proxyObj.buyHouse();
        //通过代理类调用实际上调用的是invoke()
        //代理对象和目标对象的关系?    共同实现了同一个接口(兄弟)
        System.out.println(proxyObj instanceof  Subject);//true
        System.out.println(proxyObj instanceof  RealSubject);//false
    }
 
关键问题:为什么method就是被增强方法呢?为啥调用invoke就进行了增强呢?为什么通过代理类调用方法时会被拦截并且进入invoke()方法?
1:因为将对象交由jdk动态代理了,其通过反射可以获取到类的所有信息;通过增强的对象调用原有的方法,不会执行原有的方法,而是执行代理对象的方法。
2:而代理类调用拦截器拦截方法 InvocationHandler,将增强方法对象调用的原有方法的操作拦截下来,并进行增强。InvocationHandler 重写了invoke()所以被拦截后一定会执行invoke()方法
invoke(Object proxy, Method method, Object[] args) //这三个参数也是通过反射获取到的。
(通过反射获取的方法实例,方法接口对应的方法实例,对象方法的参数数组)
3.Object invoke = method.invoke(obj, args) (类对象的实例,方法的参数数组)
底层调用了native方法:可以看出:返回方法有三个参数
 public Object invoke(Object var1, Object[] var2) throws IllegalArgumentException, InvocationTargetException {
        if (++this.numInvocations > ReflectionFactory.inflationThreshold()
 && !ReflectUtil.isVMAnonymousClass(this.method.getDeclaringClass())) 
{
            MethodAccessorImpl var3 = (MethodAccessorImpl)(
new MethodAccessorGenerator()).generateMethod
(this.method.getDeclaringClass(), this.method.getName(),
 this.method.getParameterTypes(), this.method.getReturnType(), 
this.method.getExceptionTypes(), this.method.getModifiers());
            this.parent.setDelegate(var3);
        }
        return invoke0(this.method, var1, var2);
    } 
Object proxyObj = Proxy.newProxyInstance(loader, interfaces, handler)将类加载器,接口参数,拦截器(方法增强后) 一并返回给调用增强方法的类










