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类的静 ...
随机推荐
- SQL TRACE
1.SQL TRACE说明: 参数类型 布尔型 缺省值 false 参数类别 动态 取值范围 True|false 2.类型 1)sql trace参数:alter system改变对全局进程影响,如 ...
- 解剖SQLSERVER 第四篇 OrcaMDF里对dates类型数据的解析(译)
解剖SQLSERVER 第四篇 OrcaMDF里对dates类型数据的解析(译) http://improve.dk/parsing-dates-in-orcamdf/ 在SQLSERVER里面有几 ...
- 为什么要放弃使用Thread.Sleep
前言 此文并不是说要完全放弃使用Thread.Sleep,而是要说明在符合哪些情况下使用! 场景 很多时候,我们会需要一个定时服务来处理业务. 但并不是死死的每隔N分钟执行一次那种,而是在一次处理完后 ...
- 将EnyimMemcached从.NET Core RC1升级至RC2
.NET Core RC1时project.json中的配置如下: { "version": "3.2.4", "summary": &qu ...
- Javascript图片裁切
最近浏览了不少网站的图片裁切效果,大部分的做法如下图所示(借用一张脚本之家的图片),通过改变裁切框的大小来选取合适的位置. 但本文介绍的是另外一种裁切方式,裁切框由开发者决定,图片大小由用户决定,通过 ...
- TypeScript - Classes
简介 JavaScript语言基于函数和原型链继承机制的方式构建可重用的组件.这对于OO方面编程来说显得比较笨拙.在下一代的JavaScript标准ECMAScript 6为我们提供了基于class ...
- 模拟淘宝登录和购物车功能:使用cookie记录登录名,下次登录时能够记得上次的登录名,使用cookie模拟购物车功能,使用session记住登录信息并验证是否登录,防止利用url打开网站,并实现退出登录功能
Login <%@ page language="java" contentType="text/html; charset=UTF-8" pageEnc ...
- Java线程:线程的交互
一.线程交互的基础知识 SCJP所要求的线程交互知识点需要从java.lang.Object的类的三个方法来学习: void notify() 唤醒在此对象监视器上等 ...
- JavaScript对浏览器的URL进行编码、解码
关于url编码,js有三个函数.有三个解码方法,escape,encodeURI,encodeURIComponent().有三个解码方法,unescapse,decodeURI,decodeURIC ...
- viewpage listview gridview加载本地大图多图OOM处理办法
很少上博客园写东西了. 最近在写公司项目,由于需要加载本地相册通过viewpager方式来加载, 最后发现直接进入界面就OOM了. 经过几天的整理最终搞定. 现在将加载本地和加载网络图片的缓存工具类贴 ...