java反射实现动态代理
参考:http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html
http://my.oschina.net/lyp3314/blog/136589
反射可以通过class来创建对象或者修改对象。这样就提供了一个操作对象的方法。
下面拷贝前辈的总结:
<反射机制>
为了更好的理解java的反射机制,最好先对java的泛型有所了解。java泛型就是参数化类型,即为所操作的数据类型指定一个参数。如果只指定了<?>,而没有extends,则默认是允许Object及其下的任何Java类。也就是任意类
1. Java运行时,对任意一个类,想知道它有哪些属性和方法,对于任意一个对象,想调用它的任意一个方法,都是可以实现的,这来自JAVA的反射机制
2. JAVA的反射机制主要功能:
(1)在运行时判断任意一个对象所属的类。
(2)在运行时构造任意一个类的对象。
(3)在运行时判断任意一个类所具有的成员变量和方法。
(4)在运行时调用任意一个对象的方法
前提是在运行时,不是编译时,也就是在运行前并不知道调用哪一个类,通过反射就可以做到这些
3.在JDK中,主要由以下类来实现JAVA反射机制,这些类位于java.lang.reflect包中:
Class类:代表一个类
Field 类:代表类的成员变量(成员变量也称为类的属性)。
Method类:代表类的方法。
Constructor 类:代表类的构造方法。
Array类:提供了动态创建数组,以及访问数组的元素的静态方法
4. Class类是Reflection API 中的核心类,它有以下方法
getName():获得类的完整名字
getFields():获得类的public类型的属性
getDeclaredFields():获得类的所有属性
getMethods():获得类的public类型的方法
getDeclaredMethods():获得类的所有方法
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型
getConstructors():获得类的public类型的构造方法
getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型
newInstance():通过类的不带参数的构造方法创建这个类的一个对象
<代理模式>
1. 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用
2. 代理模式一般涉及到的角色
(1)抽象角色:声明真实对象和代理对象的共同接口
(2)代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装
(3)真实角色:代理角色所代表的真实对象,是我们最终要引用的对象
【实例】
Subject 抽象类 抽象角色 定义一个抽象方法request
RealSubject 真实角色 继承了抽象类Subject 实现抽象方法request
ProxySubject 代理角色 同样继承抽象类Subject实现抽象方法request
package com.test.reflect; /**
* Created by mrf on 2015/11/26.
* 测试动态代理
* Subject 抽象类 抽象角色 定义一个抽象方法request
RealSubject 真实角色 继承了抽象类Subject 实现抽象方法request
ProxySubject 代理角色 同样继承抽象类Subject实现抽象方法request
*/
public class DynamicProxy2 { //客户端调用
public static void main(String[] args) {
Subject2 sub = new ProxySubject();
sub.request();
} }
//抽象角色
abstract class Subject2{
abstract public void request();
} //真实角色
class RealSubject2 extends Subject2{
public RealSubject2(){}
@Override
public void request() {
System.out.println("局长办事了!");
}
} //代理角色
class ProxySubject extends Subject2{
private RealSubject2 realSubject2;//以真实角色 做为代理的属性
public ProxySubject(){}
//该方法封装了真实对象的request方法
public void request() {
preRequest();
if(realSubject2==null){
realSubject2=new RealSubject2();
}
realSubject2.request();//此处执行真实对象的request方法
postRequest();
} private void postRequest() {
System.out.println("秘书回来了!");
} private void preRequest() {
System.out.println("秘书找局长");
}
}
在客户端里,并没有直接去调用真实对象中的request方法,但是却实现了真实对象中的方法,是通过代理对象间接调用的,这里体现了代理模式的特点
1. 如果要按照上述的方法使用代理模式,那么真实角色必须是事先已经存在的,并将其作为代理对象的内部属性。但是实际使用时,一个真实角色必须对应一个 代理角色,如果大量使用会导致类的急剧膨胀;此外,如果事先并不知道真实角色,该如何使用代理呢?这个问题可以通过Java的动态代理类来解决
2. 动态代理是指客户通过代理类来调用其它对象的方法
3. Java动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类:
(1)Interface InvocationHandler:该接口中仅定义了一个方法 public object invoke(Object obj,Method method, Object[] args) 在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上例中的request(),args为该方法的参数数组。 这个抽象方法在代理类中动态实现。
(2)Proxy:该类即为动态代理类,作用类似于上例中的ProxySubject
1. 动态代理的步骤
(1).创建一个实现接口InvocationHandler的类,它必须实现invoke方法
(2).创建被代理的类以及接口
(3).通过Proxy的静态方法
newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 创建一个代理
(4).通过代理调用方法
<动态代理>
实现:
package com.test.reflect; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /**
* Created by Administrator on 2015/11/24.
* 测试动态代理
*/
public class DynamicProxy {
public static void main(String[] args) {
MyInvocationHandler demo = new MyInvocationHandler();
Subject sub= (Subject)demo.bind(new RealSubject());
String info = sub.say("Rollen", 20);
System.out.println(info);
} } //定义接口
interface Subject{
public String say(String name,int age);
} //定义真实项目
class RealSubject implements Subject{
public RealSubject(){}
@Override
public String say(String name, int age) {
System.out.println(name+"开始工作");
return name+" "+age;
}
} class MyInvocationHandler implements InvocationHandler{
private Object obj;
public MyInvocationHandler(){}
public MyInvocationHandler(Subject obj){
this.obj = obj;
} public Object bind(Object obj){
this.obj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("预处理工作");
Object temp = method.invoke(this.obj,args);
System.out.println("后续工作");
return temp;
} }
java反射实现动态代理的更多相关文章
- Java反射和动态代理
Java反射 反射机制 RTTI 编译器在编译时打开和检查*.class文件 反射机制 运行时打开和检查*.class文件 Java反射常见的方法 java反射的应用 setAccessible(bo ...
- Java 反射 设计模式 动态代理机制详解 [ 转载 ]
Java 反射 设计模式 动态代理机制详解 [ 转载 ] @author 亦山 原文链接:http://blog.csdn.net/luanlouis/article/details/24589193 ...
- Java反射机制动态代理
1.什么事反射机制动态代理 在一段代码的前后动态执行其他操作,比如有一个方法是往数据库添加一个记录,我们可以通过动态代理,在操作数据库方法的前和后添加代码执行打开数据库连接和关闭数据库连接. 2.演示 ...
- java反射和动态代理实现与原理详细分析
关于Java中的动态代理,我们首先需要了解的是一种常用的设计模式--代理模式,而对于代理,根据创建代理类的时间点,又可以分为静态代理和动态代理. 一.代理模式 代理模式是常用的java设计模式, ...
- Java反射与动态代理
Java反射机制可以动态地获取类的结构,动态地调用对象的方法,是java语言一个动态化的机制.java动态代理可以在不改变被调用对象源码的前提下,在被调用方法前后增加自己的操作,极大地降低了模块之间的 ...
- Java反射 - 3(动态代理)
动态代理是对包装模式的升级,可以动态的传入需要代理的对象实现代理 准备如下 1. 被代理类的接口 2.被代理类 3.处理器:InvocationHandler 4.代理调用:Proxy.newInst ...
- Java 反射之动态代理
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt205 利用Java反射机制你可以在运行期动态的创建接口的实现.java.la ...
- java反射与动态代理的理解
一.什么是反射机制? 反射的官方定义是这样的:在运行状态中,对于任意的一个类,都能够知道这个类的所有属性和方法,对任意一个对象都能够通过反射机制调用一个类的任意方法,这种动态获取类信息及动态调用类对象 ...
- java反射以及动态代理的学习
java反射学习 1)字节码文件的三种获取方式 ①:Object类的getClass()方法:对象.getClass() ②:数据类型的静态的class属性:类名.class ③:通过Class类的静 ...
随机推荐
- 让你的Android程序更省电
app主要耗电的原因如下: 1 cpu频繁的运转 -----控制线程 2 大数据量的传输----- 数据压缩传输 3 不停的在网络间切换------------判断网络状体 4 人开发的程序后台都 ...
- Orleans 客户端请求的消息流转以及消息在Silo中再路由机制
1.客户端是一个OutSideRuntimeClient,在这个客户端类中有一个消息代理中心transport(类型为ProxiedMessageCenter) 2.ProxiedMessageCen ...
- .Net Core CLI–Ubuntu 14安装
sudo sh -c 'echo "deb [arch=amd64] http://apt-mo.trafficmanager.net/repos/dotnet/ trusty main&q ...
- [你必须知道的NOSQL系列]专题一:MongoDB快速入门
一.前言 现在越来越多的公司开始采用非关系数据库了,并且很多公司的面试都要求面试者有MongoDB的使用经验,至于非关系数据库与关系型数据库之间的区别大家可以自行百度.但是作为程序员的我们,既然大部分 ...
- RCP:解决Navigator快捷键不生效的问题
自己扩展CNF之后,导航栏的删除.复制.黏贴等快捷键失效了,在网上搜索了半天,结果最终不如自己看源码. 本篇文章的主要目的不止于解决快捷键失效,更在于如何处理类似的问题,如何利用debug快速定位.这 ...
- 公共代码参考(Volley)
Volley 是google提供的一个网络库,相对于自己写httpclient确实方便很多,本文参考部分网上例子整理如下,以作备忘: 定义一个缓存类: public class BitmapCache ...
- 【读书笔记】Html5游戏开发
一直对HMTL5做游戏饶有兴趣,而这本书刚好就是HTML5 2游戏初级入门的书.Demo简单注释详细,可以拿来练练手,一个星期左右就可以读完.若要追求酷炫高大上效果,这本书恐怕要让你失望了.但作为上手 ...
- [浅学] 1、Node.js尝试_安装&运行第一个helloworld
官网:https://nodejs.org/ 介绍:Node.js® is a platform built on Chrome's JavaScript runtime for easily bui ...
- git 修改管理
查看修改: 撤销某一文件的修改(还没提交): 撤销所有文件的修改: git checkout .
- GDT,LDT,GDTR,LDTR 详解,包你理解透彻(转)
引自:http://www.techbulo.com/708.html 一.引入 保护模式下的段寄存器 由 16位的选择器 与 64位的段描述符寄存器 构成 段描述符寄存器: 存储段描述符 选择器:存 ...