`

【Java核心-基础】反射机制 与 动态代理

    博客分类:
  • Java
 
阅读更多

Java 反射机制

很多编程语言都有“反射机制”。这项机制能让程序在运行期间 自省(introspect)。

通过这项技术,我们可以在运行期间获取类的属性、方法等元数据,甚至修改类的定义。

Java 的反射机制也一样。

 

AccessibleObject

AccesibleObject 是使用 Java 反射机制上通常会用到的类。

java.lang.reflect.Constructor、java.lang.reflect.Method、java.lang.reflect.Field 都继承自该类。

Java 9 之后,原则上只有被反射操作的模块和指定的包对反射调用者模块Open,才能使用 setAccessible(Jigsaw)。

所以虽然直接使用 setAccessible 的行为被兼容,但是存在争议。

 

动态代理

动态代理一种程序运行时动态构建代理、动态处理代理方法调用的机制。

AOP(面向切面编程)、RPC调用包装之类场景就用到了动态代理。

动态代理的实现方式有很多。Java的反射机制就是其中一种。 ASMcglibJavassist 都可以实现动态代理。

 

代理就是对调用目标的一个包装,类似设计模式里的代理模式。对目标代码的调用时通过代理对象完成的,而不是直接调用。

代理机制可以让 调用者 和 实现者 之间解耦;隐藏一些调用者不太关心的操作,提供更友好的访问方式。

 

JDK Proxy 实现动态代理

JDK Proxy 内部用到了 Java 反射机制 和 ASM。

它基于接口实现代理,即构建一个也实现了目标接口的类。

因为是基于接口的代理,代理对象的类型不是原类型,也不是原类型的子类,所以业务逻辑不能依赖于类继承关系

 

这是一个利用 JDK Proxy 实现动态代理的样例。

示例代码中指定代理实例代理所有 HelloImpl 类实现的类:HelloImpl.class.getInterfaces()

如果只想代理 Hello 接口,可以指定为 new Class<?>[]{Hello.class}

 

MyInvocationHandler.invoke 方法内部调用了实际目标方法 HelloImpl.sayHello。

此处代理方法只是输出了一行日志。可根据需求实现各种逻辑(日志、用户鉴权、全局性异常处理、性能监控、事务处理等)。

这种“全包围”的代理方式类似于 AOP 中的“环绕通知”(如,AspectJ 中的 @Around)。

 

public class MyDynamicProxy {
  public static void main(String[] args) {
    HelloImpl hello = new HelloImpl();
    MyInvocationHandler handler = new MyInvocationHandler();
    
    // 构造代理类实例
    Hello proxyHello = (Hello)Proxy.newProxyInstance(
      HelloImpl.class.getClassLoader(),
      HelloImpl.class.getInterfaces(),
      handler);

    // 调用代理方法
    proxyHello.sayHello();
  }

  interface Hello {
    void sayHello();
  }

  class HelloImpl implements Hello {
    @Override
    public void sayHello() {
      System.out.println("Hello World");
    }
  }

  class MyInvocationHandler implements InvocationHandler {
    private Object target;
    public MyInvocationHandler(Object target) {
      this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      System.out.println("Invoking sayHello");
      Object result = method.invoke(target, args);
      return result;
    }
  }
}

 

 

cglib 实现动态代理

当被代理类未实现接口,准确地说是被代理方法不属于某个接口时,我们可以用 cglib 来实现代理。

cglib 内部使用了 ASM。

它实现代理的原理是构建一个目标类的子类。与 JDK Proxy 基于接口的方式相比,该方式更近似使用被调用者本身。

Spring AOP 中也可显式指定使用 cglib。

 

JDK Proxy vs cglib

JDK Proxy 的优势

JDK Proxy 可最小化依赖关系。这可以简化开发与维护:

  • 代码实现简单
  • 可以随着JDK平滑升级
  • JDK通常比 cglib 更可靠

cglib 的优势

  • 不受“无接口”的限制

    不过,面向接口编程依然是值得推荐的原则。这对解耦及提升可测性方面非常有效。

     

  • 只操作业务所关心的类,不必增加处理其它相关类的工作量
  • 高性能

    其实 JDK Proxy 的性能也不差,在典型场景中近似 cglib

结论

与通常对待性能的技术选型一样,在没有明确的统计数据与需求前,不必纠结与选何种技术。

可靠性可维护性编程工作量都是主要的考虑因素。

 

分享到:
评论

相关推荐

    java动态代理反射机制

    java udp编程的核心代码 分为客户端和服务器端的代码部分

    Java高手真经(编程基础卷)光盘全部源码 免积分

    看到那些要积分的很不酸,发布免费版本。...javareflection.zip 26.Java反射机制与动态代理 javageneric.zip 27.Java泛型编程 javaannotation.zip 28.Java注释符编程 javafeature.zip 29.Java5.0语言新特性

    Java高手真经(编程基础卷)光盘全部源码

    看到很多人都分卷打包的,下载很是不方便,还浪费积分...javareflection.zip 26.Java反射机制与动态代理 javageneric.zip 27.Java泛型编程 javaannotation.zip 28.Java注释符编程 javafeature.zip 29.Java5.0语言新特性

    java jdk-api-1.6 中文 chmd

    java.awt.dnd Drag 和 Drop 是一种直接操作动作,在许多图形用户界面系统中都会遇到它,它提供了一种机制,能够在两个与 GUI 中显示元素逻辑相关的实体之间传输信息。 java.awt.event 提供处理由 AWT 组件所激发的...

    Java反射机制 深入浅出

    1、到底什么叫反射 2、Class类的作用 3、Class类的实例化三种...Class类在一般的基本开发是不会有任何作用的,完全可以不会,但是,对于一些高端的开发框架,所有的基本的核心原理都在于反射机制的应用上。 8、代理模式

    免费超全面的Java基础类型,容器,并发,IO流,面向对象,Web编程等代码总结

    Proxy动态代理机制详解 从整体上观察对象 网络开发 Servlet基础,生命周期执行过程 Http请求详解,握手挥手流程简介 会话跟踪技术,Session和Cookie详解 过滤器、监听器、拦截器,应用详解 Servlet 集成 C3P0

    Java2核心技术.part5

    Java2核心技术第I卷.基础知识 目录: 译者序 前言 第1章Java程序设计概述 1.1 Java程序设计平台 1.2 Java“白皮书”的关键术语 1.2.1简单性 1.2.2面向对象 1.2. 3分布式 1. 2.4健壮性 1. 2.5安仝...

    「Java学习+面试指南」一份涵盖大部分 Java 程序员所需要掌握的核心知识 准备 Java 面试,首选.zip

    Java 反射机制详解 Java 代理模式详解 BigDecimal 详解 Java 魔法类 Unsafe 详解 Java SPI 机制详解 Java 语法糖详解 集合 知识点/面试题总结 : Java 集合常见知识点&面试题总结(上) (必看 ) Java 集合常见知识点&...

    「Java学习+面试指南」一份涵盖大部分 Java 程序员所需要掌握的核心知识

    Java 反射机制详解 Java 代理模式详解 BigDecimal 详解 Java 魔法类 Unsafe 详解 Java SPI 机制详解 Java 语法糖详解 集合 知识点/面试题总结: Java 集合常见知识点&面试题总结(上) (必看 ) Java 集合常见知识点&...

    JAVA_API1.6文档(中文)

    java.awt.dnd Drag 和 Drop 是一种直接操作动作,在许多图形用户界面系统中都会遇到它,它提供了一种机制,能够在两个与 GUI 中显示元素逻辑相关的实体之间传输信息。 java.awt.event 提供处理由 AWT 组件所激发的...

    AOP技术及其在J2EE中动态代理实现

    术解决在软件开发中OOP难以解决的问题以及提高开发效率,利用JAVA的反射机制,研究了AOP的动态代理实现原 理,说明了其可行性,体现了AOP技术应用价值和发展前景。 关键词:AOP;动态代理;横切关注点

    Java动态代理简单应用

    概念  代理模式是基本的设计模式之一,它是开发者为了提供额外的或...  Java动态代理实现机制采用了反射的思想,有关于反射的基础知识,可以参见博客Java发射机制浅析。  原理  Spring核心AOP实现技术之一是采用

    java高手真经 光盘源码

    java高手真经 全光盘源代码 打包rar ...javareflection.zip 26.Java反射机制与动态代理 javageneric.zip 27.Java泛型编程 javaannotation.zip 28.Java注释符编程 javafeature.zip 29.Java5.0语言新特性

    java基础案例与开发详解案例源码全

    15.3 反射与动态代理424 15.3.1 静态代理424 15.3.2 动态代理426 15.4 本章练习427 第16章 16.1 注解概述430 16.2 JDK内置的基本注解类型430 16.2.1 重写Override430 16.2.2 警告Deprecated431 16.2.3 抑制警告...

    Java 1.6 API 中文 New

    java.awt.dnd Drag 和 Drop 是一种直接操作动作,在许多图形用户界面系统中都会遇到它,它提供了一种机制,能够在两个与 GUI 中显示元素逻辑相关的实体之间传输信息。 java.awt.event 提供处理由 AWT 组件所激发的...

Global site tag (gtag.js) - Google Analytics