在学习HadoopRPC时。用到了函数调用。函数调用都是採用的java的反射机制和动态代理来实现的,所以如今回想下java的反射和动态代理的相关知识。

一、反射

JAVA反射机制定义: JAVA反射机制是java程序在执行状态中。对于随意一个类,都能够知道这个类的所有属性和方法;对于随意一个对象,都能够调用它的随意一个方法;这样的动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 

反射就是把Java类中的各种成分映射成对应的Java类。

Java反射机制主要提供了下面功能: 

1、在执行时推断随意一个对象所属的类。
2、在执行时构造随意一个类的对象;
3、在执行时推断随意一个类所具有的成员变量和方法;
4、在执行时调用随意一个对象的方法;
5、生成动态代理。

我们了解了反射机制的功能,那么我们怎样详细来实现它呢?

 一个类中的每一个成员都能够用对应的反射包中的一个类的实例对象来表示,通过Class类的方法能够得到这些实例对象。这个“成员”就包括:类的构造函数、成员变量、方法等一些信息。而他们所对应的反射包中的类各自是:Constructor类、Field类、Method类。

这里仅仅要讲讲动态代理的知识。

二、动态代理

  Java动态代理类位于Java.lang.reflect包下,一般主要涉及到下面两个类:
    (1). Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method, Object[] args)。在实际使用时。第一个參数obj通常是指代理类。method是被代理的方法,如上例中的request()。args为该方法的參数数组。

这个抽象方法在代理类中动态实现。 

    (2).Proxy:该类即为动态代理类。作用相似于上例中的ProxySubject,当中主要包括下面内容: 

      Protected Proxy(InvocationHandler h):构造函数。预计用于给内部的h赋值。 

      Static Class getProxyClass (ClassLoader loader, Class[] interfaces):获得一个代理类。当中loader是类装载器,interfaces是真实类所拥有的所有接口的数组。 

      Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类能够当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。

 实例:

1、定义一个HelloWorld接口

 /**
* 定义一个HelloWorld接口
*
* @author
*
*/
public interface HelloWorld {
public void sayHelloWorld();
}

2、类HelloWorldImpl是HelloWorld接口的实现

 /**
* 类HelloWorldImpl是HelloWorld接口的实现
*
* @author
*
*/
public class HelloWorldImpl implements HelloWorld{ public void sayHelloWorld() {
System.out.println("HelloWorld!");
} }

3、HelloWorldHandler是 InvocationHandler接口实现

 import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; /**
* 实如今方法调用前后向控制台输出两句字符串
*
* @author
*
*/
public class HelloWorldHandler implements InvocationHandler{
//要代理的原始对象
private Object obj; public HelloWorldHandler(Object obj) {
super();
this.obj = obj;
} /**
* 在代理实例上处理方法调用并返回结果
*
* @param proxy 代理类
* @param method 被代理的方法
* @param args 该方法的參数数组
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
//调用之前
doBefore();
//调用原始对象的方法
result=method.invoke(obj, args);
//调用之后
doAfter();
return result;
} private void doBefore(){
System.out.println("before method invoke");
} private void doAfter(){
System.out.println("after method invoke");
} }

4、測试类

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy; public class HelloWorldTest { public static void main(String[] args) {
HelloWorld helloWorld=new HelloWorldImpl();
InvocationHandler handler=new HelloWorldHandler(helloWorld); //创建动态代理对象
HelloWorld proxy=(HelloWorld)Proxy.newProxyInstance(
helloWorld.getClass().getClassLoader(),
helloWorld.getClass().getInterfaces(),
handler);
proxy.sayHelloWorld();
}
}

执行结果为:

before method invoke

HelloWorld

after method invoke

总结:

一个典型的动态代理创建对象过程可分为下面四个步骤:
1、通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(...);

2、通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类
Class clazz = Proxy.getProxyClass(classLoader,new Class[]{...});

3、通过反射机制获取动态代理类的构造函数,其參数类型是调用处理器接口类型
Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});

4、通过构造函数创建代理类实例。此时需将调用处理器对象作为參数被传入Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));

为了简化对象创建过程。Proxy类中的newInstance方法封装了2~4。仅仅需两步就可以完毕代理对象的创建。

生成的ProxySubject继承Proxy类实现Subject接口。实现的Subject的方法实际调用处理器的invoke方法,而invoke方法利用反射调用的是被代理对象的的方法(Object result=method.invoke(proxied,args))

综合上面所说的,作为一个Dynamic Proxy,它必须满足下面三个条件:
        1、实现了InvocationHandler接口,实现接口中定义的invoke方法。
        2、包括接口实现类的实例;
        3、通过Proxy.newProxyInstance方法实现Proxy与接口之间的绑定
再来回想一下定义
 Dynamic Proxy是这样一种class:它是在执行时生成的class,在生成它时你必须提供一组interface给它。然后该class就宣称它实现了这些 interface。你当然能够把该class的实例当作这些interface中的不论什么一个来用。

当然啦,这个Dynamic Proxy事实上就是一个Proxy。它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作   。

java反射机制与动态代理的更多相关文章

  1. Java反射机制以及动态代理

    Java反射机制以及动态代理 Java反射机制 含义与功能 Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类 ...

  2. Java反射机制可以动态修改实例中final修饰的成员变量吗?

    问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...

  3. 【java】java反射机制,动态获取对象的属性和对应的参数值,并属性按照字典序排序,Field.setAccessible()方法的说明【可用于微信支付 签名生成】

    方法1:通过get()方法获取属性值 package com.sxd.test.controller; public class FirstCa{ private Integer num; priva ...

  4. java.lang.Class<T> -- 反射机制及动态代理

    Interface : Person package java_.lang_.component.bean; public interface Person { String area = " ...

  5. 【Java基础】java中的反射机制与动态代理

    一.java中的反射机制 java反射的官方定义:在运行状态下,可以获取任意一个类的所有属性和方法,并且可通过某类任意一对象实例调用该类的所有方法.这种动态获取类的信息及动态调用类中方法的功能称为ja ...

  6. Java的反射机制和动态代理

    介绍Java注解的时候,多次提到了Java的反射API.与javax.lang.model不同的是,通过反射API可以获取程序在运行时刻的内部结构.反射API中提供的动态代理也是非常强大的功能,可以原 ...

  7. java反射机制与动态加载类

    什么是java反射机制? 1.当程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言.我们认为java并不是动态语言,但是它却有一个非常突出的动态相关机制,俗称:反射. IT行业里这么说,没有 ...

  8. Java中的反射机制和动态代理

    一.反射概述 反射机制指的是Java在运行时候有一种自观的能力,能够了解自身的情况为下一步做准备,其想表达的意思就是:在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法:对于任意一个对象 ...

  9. java反射中的动态代理机制(有实例)

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

随机推荐

  1. java文件读写工具类

    依赖jar:commons-io.jar 1.写文件 // by FileUtilsList<String> lines = FileUtils.readLines(file, " ...

  2. 学习 TList 类的实现[5]

    先来实现 TMyList.SetCapacity. 马上会想到下面代码: procedure TMyList.SetCapacity(const Value: Integer); begin   if ...

  3. error C2065: “m_Pic”: 未声明的标识符

    public: CPicture m_Pic; 要写在头文件里! 而不能是cpp文件的public里!

  4. php中一些常用的语句收集

    清空数据表   truncate 表名; http://blog.knowsky.com/234205.htm    常用的SQL语句实例 http://blog.csdn.net/vericlong ...

  5. POJ 1273 Drainage Ditches (网络最大流)

    http://poj.org/problem? id=1273 Drainage Ditches Time Limit: 1000MS   Memory Limit: 10000K Total Sub ...

  6. Effective C++ Item 35 Consider alternatives to virtual functions

    考虑你正在为游戏人物设计一个继承体系, 人物有一个函数叫做 healthValue, 他会返回一个整数, 表示人物的健康程度. 由于不同的人物拥有不同的方式计算他们的健康指数, 将 healthVal ...

  7. swift - UISlider 的用法

    swift的UISlider的用法和oc基本没有区别 1.创建 class SecondViewController: UIViewController { var slider = UISlider ...

  8. hadoop命令fsck命令

    在HDFS中,提供了fsck命令,用于检查HDFS上文件和目录的健康状态.获取文件的block块信息和位置信息等. 具体命令介绍: -move: 移动损坏的文件到/lost+found目录下 -del ...

  9. 查看网卡流量:sar

    sar(System Activity Reporter 系统活动情况报告)是目前 Linux 上最为全面的系统性能分析工具之一,可以从多方面对系统的活动进行报告,但我们一般用来监控网卡流量 [roo ...

  10. MQTT协议笔记之mqtt.io项目HTTP协议支持

    前言 MQTT协议诞生之初,就未曾考虑通过HTTP传输.这也正常,网络受限.不稳定网络不太适合HTTP(2G/3G网络大家使用WAP不也OK嘛).在网络较为充裕的桌面端而言,虽纯文本对比二进制而言没多 ...