JDBC动态代理

对动态代理的原理的解释

重要参考


对生成代理对象和方法调用的过程分析

  • 1.调用Proxy.newProxyInstance()方法动态生成代理对象
    在这个过程我们传入了目标类的类加载器(即被代理类)和代理类需要实现的接口数组。JDK使用一种称为“字节码技术”的方法来生成代理类的字节码。
    1.JDK使用提供的类加载器加载生成的代理类的字节码,并通过反射创建一个代理类的实例。这个实例就是最终的动态代理对象。
    2.将InvocationHandler实现与代理对象关联:在创建动态代理对象时,JDK会将你提供的InvocationHandler实现对象与代理对象关联起来。这样,当代理对象上的方法被调用时,就会调用InvocationHandler的invoke方法。

  • 2.当代理对象调用方法时分析
    jdk自动将我们的代理对象和InvocationHandler接口的实现类相关联起来了,当我们调用代理对象中的方法的时候将会自动调用实现类中重写的
    invoke方法,实现方法增强

动态生成的代理类的脑补实现(示意图,无法执行)

  • 动态生成的代理类我们看不到类,但是我们可以分析一下他的组成结构
package com.itheima.domain;

public class LeaderProxy implements IWork{
    //关联InvocationHandler接口的实现类
    WorkInvocationHandler handler = new WorkInvocationHandler();
    @Override
    public void meeting() {
        //将方法调用转发给WorkInvocationHandler中的invoke方法
        //传入动态生成的代理对象
        //代理的方法
        //方法需要的参数
       return handler.invoke(proxy,method,args);
    }

    @Override
    public int evaluate(String name) {
        //将方法调用转发给WorkInvocationHandler中的invoke方法
        //传入动态生成的代理对象
        //代理的方法
        //方法需要的参数
        return handler.invoke(proxy,method,args);
    }
}

发现和静态代理相比

  • 1.静态代理关联被代理类,增强部分在代理类中写
  • 2.动态代理类,关联InvocationHandler接口的实现类,InvocationHandler接口的实现类关联被代理类,增强部分在实现类中写

但是动态代理类在间接上是管理被代理类的,增强部分间接是在动态代理类中写的。所以本质上代理类和动态代理类是一样的

package com.proxy;

public interface UserDao {
    //计算2个整数的和
    public void add ();
}

package com.proxy;

public class UserDaoImpl implements UserDao{
    @Override
    public void add() {
        System.out.println("被增强方法执行");
    }
}

package com.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

//代理类实现InvocationHandler接口
public class UserDaoImplProxy implements InvocationHandler {
    //被代理类的对象
    private  Object obj;
    //将被代理类的对象传递进来
    public UserDaoImplProxy(Object obj){
        this.obj=obj;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("前置增强....");
        //被增强的方法执行
        final Object res = method.invoke(obj, args);
        System.out.println("后置增强.....");

        return res;
    }
}

package com.proxy;

import java.lang.reflect.Proxy;

public class Main {



    public static void main(String[] args) {

        //被代理类的接口(参数二)
        Class[] interfaces = {UserDao.class};
        //实现InvocationHandler接口的代理类
      UserDaoImpl userDaoImpl = new UserDaoImpl();

        final UserDao proxyInstance =
                (UserDao) Proxy.newProxyInstance(UserDao.class.getClassLoader(), interfaces, new UserDaoImplProxy(userDaoImpl));

     proxyInstance.add();

    }
}

posted @ 2023-11-28 17:19  一往而深,  阅读(25)  评论(0编辑  收藏  举报