这一篇将会讲到利用java的反射机制而设计的动态代理模式。
•代理模式一般涉及到的角色有
抽象角色:声明真实对象和代理对象的共同接口。
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。
如果像上面描述那样,每个代理角色“都持有对真实对象的引用,并同时提供与真实对象相同的接口一遍在任何时刻代替真实对象”的话,那么我们可以很容易想象,随着需要代理的类增多,很快就会出现“类爆炸”的现象。
动态代理,是指在不知道真实角色的情况下,去调用正确的方法。
其实很简单,不要想得太复杂了,就是利用监听传进来的对象,在调用此方法时,在这方法之间做一个调用。
好啦,直接代码吧:
首先是抽象角色
[java] view plaincopyprint?package com.insigma.dymic;
public interface Subject {
public void request();
}
package com.insigma.dymic;
public interface Subject {
public void request();
}
真实角色,就直接实现这接口就可以了
[java] view plaincopyprint?package com.insigma.dymic;
public class RealSubject implements Subject{
@Override
public void request() {
System.out.println("RealSubject do this");
}
}
package com.insigma.dymic;
public class RealSubject implements Subject{
@Override
public void request() {
System.out.println("RealSubject do this");
}
}
代理角色:
[java] view plaincopyprint?package com.insigma.dymic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicSubject implements InvocationHandler{
private Object sub;
public DynamicSubject(){
}
public DynamicSubject(Object object){
sub = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("before calling " + method);
method.invoke(sub, args);
System.out.println("after calling " + method);
return null;
}
}
package com.insigma.dymic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicSubject implements InvocationHandler{
private Object sub;
public DynamicSubject(){
}
public DynamicSubject(Object object){
sub = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("before calling " + method);
method.invoke(sub, args);
System.out.println("after calling " + method);
return null;
}
}
使用代理角色的客户端:
[java] view plaincopyprint?package com.insigma.app;
import java.lang.reflect.InvocationHandler;
import com.insigma.dymic.DynamicSubject;
import com.insigma.dymic.ProxyUtil;
import com.insigma.dymic.RealSubject;
import com.insigma.dymic.Subject;
public class DynamicProxyApp {
public static void main(String[] args) {
Subject sub = new RealSubject();
sub = (Subject) ProxyUtil.getInstance(sub);
sub.request();
}
}
package com.insigma.app;
import java.lang.reflect.InvocationHandler;
import com.insigma.dymic.DynamicSubject;
import com.insigma.dymic.ProxyUtil;
import com.insigma.dymic.RealSubject;
import com.insigma.dymic.Subject;
public class DynamicProxyApp {
public static void main(String[] args) {
Subject sub = new RealSubject();
sub = (Subject) ProxyUtil.getInstance(sub);
sub.request();
}
}
客户端的工具类:
[java] view plaincopyprint?package com.insigma.dymic;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
public class ProxyUtil {
public static Object getInstance(Object obj){
InvocationHandler ds = new DynamicSubject(obj);
Class cls = obj.getClass();
Class c = Proxy.getProxyClass(cls.getClassLoader(), cls.getInterfaces());
try {
Constructor cons = c.getConstructor(new Class[]{InvocationHandler.class});
obj = cons.newInstance(new Object[]{ds});
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return obj;
}
}
package com.insigma.dymic;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
public class ProxyUtil {
public static Object getInstance(Object obj){
InvocationHandler ds = new DynamicSubject(obj);
Class cls = obj.getClass();
Class c = Proxy.getProxyClass(cls.getClassLoader(), cls.getInterfaces());
try {
Constructor cons = c.getConstructor(new Class[]{InvocationHandler.class});
obj = cons.newInstance(new Object[]{ds});
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return obj;
}
}
其实理清思路之后很简单,整一个测试的手敲代码连50行都没有。关键是要自己去想,自己想明白的才是你理解到的。
分享到:
相关推荐
Java反射技术浅谈 Java反射技术是一种强大的技术,它允许Java程序访问、检测和修改它自己的状态或行为。通过反射,Java程序可以加载一个运行时才知道名称的类,获取其完整的内部信息,并创建其对象,或者对其属性...
### 浅谈Java代理机制 #### 一、引言 在深入探讨Java代理机制之前,我们首先需要了解代理模式的基本概念及其应用场景。代理模式是一种结构型设计模式,它为其他对象提供了一种代理以控制对这个对象的访问。在Java...
在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包。 * Class类:代表一个类。 * Field类:代表类的成员变量(成员变量也称为类的属性)。 * Method类:代表类的方法。 * Constructor类:...
"浅谈Java程序设计在线开放课程"这个主题,将深入探讨Java语言的核心概念、编程实践以及如何通过在线平台有效地学习这门技术。 Java以其“一次编写,到处运行”的跨平台特性,成为了企业级应用开发的首选语言。课程...
浅谈MyBatis通用Mapper实现原理 MyBatis通用Mapper是MyBatis框架中的一种通用Mapper实现方式,主要提供了一些通用的方法,这些方法是以接口的形式提供的。通用Mapper的实现原理主要是通过Java反射机制和MyBatis框架...
在Java中,虽然其类型系统相对固定,但可以通过一些技术来扩展其灵活性,例如使用泛型、反射和动态代理等。泛型提供了一种在编译时处理类型的方式,而反射允许在运行时检查和操作类的结构,动态代理则能实现接口的...
### Java之浅谈深说——教你如何成长为Java编程高手 在IT行业中,Java作为一种广泛使用的编程语言,其重要性不言而喻。对于希望成为Java编程高手的学习者来说,掌握正确的学习路径至关重要。本文将根据提供的标题、...
总之,Java虽然没有内置的事件驱动机制,但通过观察者模式和反射机制,我们可以构建出符合需求的事件驱动系统。观察者模式更适用于通用和灵活的场景,而反射则适合对已知对象结构的简单事件处理。在实际开发中,应...
浅谈Java中对类的主动引用和被动引用 Java 中的类引用可以分为两种:主动引用和被动引用。理解这两种引用机制对于 Java 程序的正确执行和优化至关重要。 一、主动引用 主动引用是指在 Java 程序中明确地使用某个...
在Java编程语言中,`Class`类扮演着至关重要的角色,它是Java反射机制的基础。`Class`类代表了运行时的类信息,允许我们在程序运行时动态地获取类的结构和属性,包括类的成员变量、方法、构造器等。这使得Java具备了...
Java Properties类的使用基础 Java Properties类是Java标准库中的一种配置类,继承自HashTable,通常...Java Properties类是Java标准库中的一种配置类,提供了便捷的配置信息读写和持久化机制,广泛应用于实际项目中。
浅谈使用java实现阿里云消息队列简单封装 本文主要介绍了使用Java实现阿里云消息队列的简单封装,包括对阿里云消息队列的介绍、设计方案、消息发送和接收的实现等。 一、阿里云消息队列简介 阿里云提供了两种消息...
本文将深入探讨Java中的内存泄露及其相关的JVM垃圾回收机制。 首先,与C++等语言不同,Java引入了垃圾回收(Garbage Collection, GC)机制,自动负责管理内存,避免程序员手动释放内存可能导致的错误。然而,这并不...
11. **JNI与JVM原理**:浅谈Java Native Interface(JNI),用于在Java程序中调用本地(非Java)代码,以及JVM的工作原理,包括类加载、内存管理和垃圾收集。 12. **案例分析**:可能包含一些简单的编程实例,帮助...
1. **创建方式**:`newInstance()`是通过反射机制来创建对象,而`new`是直接创建。`newInstance()`要求类必须有一个无参构造器,而`new`可以调用任何公共构造器。 2. **灵活性与效率**:`newInstance()`提供了更大...
### Java程序员初学20道题知识点解析 #### 1....- **泛型与反射**:掌握泛型的使用以及反射机制的应用。 以上是针对“Java程序员初学20道题”中所提到的知识点的具体解析。希望对Java初学者有所帮助。
浅谈计算机应用软件开发中编程语言的选择研究 随着信息技术的飞速发展,计算机应用软件已经深入到我们生活的各个领域,从个人娱乐、办公自动化到工业自动化、云计算等,无处不在。软件开发企业面临着激烈的市场竞争...
浅谈对象与Map相互转化 在 Java 开发中,对象与 Map 的相互转换是非常常见的需求。例如,在 Web 项目中,我们需要将 Java 对象转换为 JSON 数据,以便于前端 JavaScript 代码对其进行处理。又或者,在数据处理时,...