JDK动态代理知识的一些理解

本文详细介绍了Java代理模式的两种实现方式:静态代理和动态代理。在静态代理中,通过手动创建代理类来扩展目标类的功能,但当目标类或接口改变时,需要大量修改代码。动态代理则利用JDK或Cglib实现,能够在运行时动态创建代理对象,减少代码维护工作。示例代码展示了如何创建接口、目标类、代理类以及如何使用JDK动态代理实现功能增强。
摘要由CSDN通过智能技术生成

使用代理的好处:功能增强,控制访问

 

1.静态代理

代理类是自己手工实现,自己创建一个java类,表示代理类,同时所要代理的目标对象是确定的

特点:实现简单,容易理解

缺点:当目标类增加了,代理类也需要成倍的增加(类爆炸),当接口功能增加了会影响众多的实现类

举例:

定义方法--创建一个接口 UsbSell   定义一个sell方法

package com.example.demo.proxy.staticproxy;

/**
 * @author hanzl
 * @date 2021/1/31 8:44 下午
 * 接口
 */
public interface UsbSell {
 //定义方法
  public int sell(int count);
}

创建目标类  UsbFactory 实现 UsbSell 接口  

package com.example.demo.proxy.staticproxy;

/**
 * @author hanzl
 * @date 2021/1/31 8:44 下午
 * 目标类
 */
public class UsbFactory implements UsbSell {

  @Override
  public int sell (int count) {
    return 80;
  }
}

创建代理类 Taobao 实现 UsbSell 接口   目的是扩展目标类的功能

package com.example.demo.proxy.staticproxy;

/**
 * @author hanzl
 * @date 2021/1/31 8:45 下午
 *  代理类
 */
public class Taobao implements UsbSell {
  private UsbFactory usbFactory=new UsbFactory();
  
  @Override
  public int sell (int count) {
   int res= usbFactory.sell(count);
     System.out.println("执行了代理类的方法");
    //扩展功能
    res+=res+20;
    return res;
  }
}

测试静态代理

package com.example.demo.proxy.staticproxy;

/**
 * @author hanzl
 * @date 2021/1/31 8:48 下午
 * 测试
 */
public class TestMain {

  public static  void main(String args[]){
    Taobao taobao=new Taobao();
    taobao.sell(5);
  }

}

2.动态代理

特点:代理类数量可以很少;    当修改接口中的方法时,不会影响代理类;   程序执行过程中,使用jdk代理目标对象是活动的,利用反射机制可以给不同的目标对象创建代理

Jdk动态代理:使用反射包中的类和接口实现, Jdk动态代理必须使用接口  ,反射包中的 invocationhandler,Method, proxy

Cglib动态代理:核心是继承

Jdk动态代理实现的核心:

1.创建接口:定义目标类要完成的功能

package com.example.demo.proxy.dynamic;

/**
 * @author hanzl
 * @date 2021/1/31 9:19 下午
 * 创建接口,定义方法
 */
public interface Singer {
//定义唱歌的方法
  public String sing(String s);

}

2.创建目标类实现接口

package com.example.demo.proxy.dynamic;

/**
 * @author hanzl
 * @date 2021/1/31 9:20 下午
 * 目标类,刘德华,实现唱歌的功能
 */
public class Liudehua implements Singer{

  @Override
  public String sing (String s) {
    s="hello,"+s+"给我一杯忘情水";
    System.out.println(s);
    return  s;
  }
}

3.创建invocationhandler接口实现类,在invoke方法中完成代理类的功能:即调用目标方法,增强功能

package com.example.demo.proxy.dynamic;

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

/**
 * @author hanzl
 * @date 2021/1/31 9:22 下午
 * 自定义MyInvocationHandler 实现 InvocationHandler 接口
 */
public class MyInvocationHandler implements InvocationHandler {
  private Object target=null;

  public MyInvocationHandler(Object target){
    this.target=target;
  }
  @Override
  public Object invoke (Object proxy, Method method, Object[] args) throws Throwable {
    Object res=method.invoke(target,args);
    System.out.println("执行了代理:"+res.toString());
    return res;
  }
}

4.使用proxy类的静态方法,创建代理对象,调用方法

 

package com.example.demo.proxy.dynamic;

import java.lang.reflect.Proxy;

/**
 * @author hanzl
 * @date 2021/1/31 9:26 下午
 * 测试动态代理
 */
public class TestMain {
  public static void main(String args[]){
    //目标对象
    Singer target=new Liudehua();
    MyInvocationHandler myInvocationHandler=new MyInvocationHandler(target);
    Singer singer=(Singer)Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),myInvocationHandler);
    singer.sing("hanzl");
  }

}

5.执行结果

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值