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类的静 ...
随机推荐
- @MappedSuperclass的用法
实体类baseEntity.java package com.rock.cft.hibernate; import java.util.Date; import javax.persistence.G ...
- C#/net 使用Protocol Buffers入门
Protocol buffers 是一个由谷歌开发的开源的编码机制用于将结构化的数据序列化或者反序列化,被设计成语言以及平台中立,protobuff比xml更简单比json还要紧凑一些,网上有一些关于 ...
- Sensor(LIGHT)
package com.example.sensor01; import java.util.List; import android.hardware.Sensor; import android. ...
- 基础调试命令 - u/ub/uf
在调试过程中难免会遇到需要反编译代码来分析逻辑的时候,在windbg中,需要反编译代码就要用到u/ub/uf这三个命令.本文这里分别介绍这三个命令各自的用途. 以下是一个quick sort的实例代码 ...
- Linux Shell变量
200 ? "200px" : this.width)!important;} --> 介绍 变量是shell脚本中必不可少的组成部分,在脚本中使用变量不需要提前声明.在ba ...
- python Web开发框架-Django (1)
以前用web.py(另外一款轻量级web开发框架)做一个监控管理平台,没有做特别的记录就不好拾起来.最近做一个日志聚合系统,使用的是django,这次就记下来,方便查询. Django是一个高效的we ...
- Lucene系列-分析器
分析器介绍 搜索的基础是对文本信息进行分析,Lucene的分析工具在org.apache.lucene.analysis包中.分析器负责对文本进行分词.语言处理得到词条,建索引和搜索的时候都需要用到分 ...
- Js~动态判断PC和手机浏览器
这个只是一个小知识,也是在网上找的,挺好用! 动态判断浏览器是PC还是移动端! <script> var browser={ versions:function(){ var u = na ...
- Atitit Atitit 图像处理之 Oilpaint油画滤镜 水彩画 源码实现
Atitit Atitit 图像处理之 Oilpaint油画滤镜 水彩画 源码实现 1.1. 具体原理参考1 2. 水彩画滤镜算法如下:1 2.1. 这个其实就是灰度层次降低维度的过程.2 2.2. ...
- Atitit 如何让精灵控件运动
Atitit 如何让精灵控件运动 ##让Sushi精灵动起来 上面的代码,我们创建了静态的sushiSprite,现在我们让它动起来.使它从屏幕顶部下落到屏幕底部.在addSushi方法中添加如下代 ...