2020最新更新-jdk动态代理

2020最新更新-jdk动态代理

1、什么是动态代理
使用jdk的反射机制,创建对象的能力,创建的是代理类的对象。不用你创建文件,不用写java文件。
动态:是指,在程序执行时,调用jdk提供的方法才能创建代理类的对象
在程序的执行过程中使用jdk的反射机制,创建代理类对象,并动态的指定要代理的目标类
动态代理是一种创建java对象的能力,让你不用自己创建对象,就能代理类创建对象。
2、实现方式
cglib动态代理(第三方的工具库,原理是继承,通过继承目标类,创建他的子类,在子类中重写父类中同名的方法,实现功能的修改,所以要求目标类不能是final的。
在很多框架中使用,mybatis和spring中都有使用,对于无接口的类,需要使用这种方式)

===========================================
jdk动态代理(必须有接口)
jdk动态代理:使用jdk反射提供的类和接口实现动态代理的功能。
相关接口和类的详细讲解
java,lang.reflect包下的三个类:InvocationHandler、Method、Proxy
InvocationHandler接口(调用处理器):就一个方法invoke(),表示代理对象要执行的功能代码,你的代理类要完成的功能就在这个方法中
怎么用InvocationHandler
创建一个类实现InvocationHandler,重写invoke()
public Object invoke(Object proxy, Method method, Object[] args)

  • Object proxy:jdk创建的代理对象,无需赋值。
  • Methos:目标类中的方法,jdk中提供的method对象的
  • Object[] args:目标类中方法的参数

Method类:表示方法的,确切的说是目标类的方法
作用:通过Method可以执行某个目标类方法,核心方法为invoke()
Method.invoke()
public Object invoke(Object obj, Object… args)
public Object invoke(目标对象,方法的参数)
Proxy类:创建代理对象。之前都是创建对象都是new类的构造方法,现在是用Proxy类的方法,代替new的使用
方法:静态方法 newProxyInstance()
作用是创建代理对象,等同于代理中 A a = new A();
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)

  • ClassLoader:类加载器,负责向内存中加载对象,使用反射获取对象的ClassLoader
    获取ClassLoader利用反射如下
    a.getClass().getClassLoader() (目标对象的类加载器)
  • Class<?>[] interfaces:目标对象实现的接口,也是反射获取的 a.getClass().getInterfaces()
  • InvocationHandler:我们自己写的,代理类要完成的功能

3、动态代理能做什么
可以在不改变原来目标方法的功能前提下,可以在代理中增强自己的功能代码,达到功能增强

4、示例代码用来理解上面的概念
注意:jdk代理必须要有接口才能使用

  • 接口
public interface UserDao {
	//所谓增强就是在已经写好的代码基础上进行功能扩展,但是又不在原来代码上改动,这个时候代理就有用了
   public int query(String name);
}
  • 实现类
public class UserDaoImp implements UserDao {
    @Override
    //我就是目标类,代理类就是来增强我的,我返回2,但是最终结果想返回4,我可以在代理类中修改我的结果
    public int query(String name) {
        System.out.println("我是目标类的输出");
        return 2;
    }
}
  • 代理类
public class UserDaoProxy implements InvocationHandler {
	//这个就是用构造方法获取目标类就是上面的UserDao 
    private  Object target;
    public UserDaoProxy(Object target){
        this.target = target;
    }
	//重写InvocationHandler接口的invoke方法,代理对象要执行的功能代码,你的代理类要完成的功能就在这个方法中
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 这里可以做增强 可在目标方法之前执行你要增强的内容 也可以在后面
        System.out.println("我是前面====");
        //通过Method类利用目标对象获取你要增强的方法
        Object result = method.invoke(target, args);
        if(result!=null){
            Integer num = (Integer)result;
            result = num*2;
        }
        return result;
    }
}

  • 测试方法
public class Main {

    public static void main(String[] args) {
    	//目标对象
        UserDao user = new UserDaoImp();
        //代理对象
        UserDaoProxy invocationHandler = new UserDaoProxy(user);
        //通过Proxy类创建代理对象
        UserDao proxy = (UserDao) Proxy.newProxyInstance(user.getClass().getClassLoader(), user.getClass().getInterfaces(), invocationHandler);
		//返回结果肯定是代理类中已经乘以2的结果 4
        Integer res = proxy.query("33333");
        System.out.println("期望的返回结果=="+res);
        proxy.add();
    }
}
  • 查看测试结果
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值