Java JDK * 实现原理实例解析

作者:夏的世界的伤 时间:2022-04-23 05:19:10 

JDK * 实现原理

* 机制

通过实现 InvocationHandler 接口创建自己的调用处理器

通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建 * 类

通过反射机制获得 * 类的构造函数,其唯一参数类型是调用处理器接口类型

通过构造函数创建 * 类实例,构造时调用处理器对象作为参数被传入

Interface InvocationHandler

该接口中仅定义了一个方法Object:invoke(Object obj,Method method,Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组。这个抽象方法在代理类中动态实现。

Proxy

该类即为 * 类

Protected Proxy(InvocationHandler h)

构造函数,用于给内部的h赋值

Static Class getProxyClass (ClassLoader loader,Class[] interfaces)

获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组
Static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)

返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)

Dynamic Proxy

它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些 interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。

代码示例

创建接口:


/**
* @CreateDate: 2019/6/17 14:52
* @Version: 1.0
*/
public interface BuyService {
 String buyPhone();
 String buyComputer();
}

创建实现类:


public class BuyServiceImpl implements BuyService {

@Intercept("buyPhone")
 @Override
 public String buyPhone() {
   try {
     TimeUnit.SECONDS.sleep(1);
   } catch (InterruptedException e) {
     e.printStackTrace();
   }
   System.out.println("==========BuyServiceImpl.class=============" + " buyPhone");
   this.buyComputer();
   return "buy phone";
 }

@Intercept("buyComputer")
 @Override
 public String buyComputer() {
   try {
     TimeUnit.SECONDS.sleep(1);
   } catch (InterruptedException e) {
     e.printStackTrace();
   }
   System.out.println("==========BuyServiceImpl.class=============" + " buyComputer");
   return "buy computer";
 }
}

创建 InvocationHandler:


public class ReflectionHandler implements InvocationHandler {

private Object target;

public ReflectionHandler(Object target) {
   this.target = target;
 }

public <T> T getProxy(){
   return (T) Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
 }

@Override
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   return method.invoke(target,args);
 }
}

创建启动类:


public class Bootstrap {

public static void main(String[] args) {

// * 实现
   ReflectionHandler reflectionHandler = new ReflectionHandler(new BuyServiceImpl());

BuyService proxy = reflectionHandler.getProxy();

String computer = proxy.buyComputer();

String phone = proxy.buyPhone();

System.out.println(computer + "\r\n" + phone);
 }

来源:https://www.cnblogs.com/hkMblogs/p/13171733.html

标签:Java,JDK,动态,代理
0
投稿

猜你喜欢

  • java开发ShardingSphere的路由引擎类型示例详解

    2023-11-29 01:18:56
  • 使用@TransactionalEventListener监听事务教程

    2023-10-05 02:50:44
  • 浅谈Java中复制数组的方式

    2022-04-14 23:30:27
  • 新手入门Jvm-- JVM对象创建与内存分配机制

    2021-11-04 19:28:10
  • 基于sharding-jdbc的使用限制

    2023-09-01 12:33:58
  • Lombok中@EqualsAndHashCode注解的使用及说明

    2023-11-30 04:47:05
  • C# 获取当前年份的周期及周期所在日期范围(推荐)

    2021-10-06 15:00:44
  • 线程池中execute与submit的区别说明

    2023-03-18 23:09:04
  • Caused by: java.lang.ClassNotFoundException: org.apache.commons.collections.Transformer异常

    2022-07-03 11:12:34
  • 用Flutter开发自定义Plugin的方法示例

    2023-07-05 00:19:40
  • C++找出字符串中出现最多的字符和次数,时间复杂度小于O(n^2)

    2023-06-22 07:32:31
  • SpringBoot集成阿里云OSS图片上传

    2021-08-15 21:01:55
  • 详解Servlet3.0新特性(从注解配置到websocket编程)

    2023-08-08 14:29:48
  • Java中的synchronized关键字

    2023-07-28 18:39:26
  • Map与JavaBean相互转换的工具类 

    2021-09-22 20:59:02
  • Spring中的@Transactional的工作原理

    2023-08-06 02:00:04
  • Spring JPA联表查询之OneToOne源码详解

    2022-08-06 13:57:55
  • 基于java构造方法Vector删除元素源码分析

    2023-11-25 14:54:45
  • Java Apache common-pool对象池介绍

    2022-08-24 22:53:06
  • Java使用Lettuce客户端在Redis在主从复制模式下命令执行的操作

    2023-11-28 21:38:19
  • asp之家 软件编程 m.aspxhome.com