`
sw1982
  • 浏览: 511545 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Proxy模式1--JAVA中的代理实现

阅读更多

一。首先需要了解下面3个类的API:java系统支持的代理就是这3个类+反射来实现。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

 

二。下面的这段测试代码,目的就是:将一个ArrayList对象的操作进行代理,每个method前后都输出一行字符串。

核心代码是

Class clz = ArrayList.class;
Object proxyed_Object = Proxy.newProxyInstance(clz.getClassLoader(),
         clz.getInterfaces(), new MyInvocationHandle(new ArrayList(10)));

生成一个ArrayList的代理的对象。

package proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

/**
 * DEMO:测试java中的代理
 * 
 * 代理了一个ArrayList对象,并在调用方法前后各加了一个systemout输出
 * @author wei.songw
 * 
 */
public class MyInvocationHandle implements InvocationHandler {

	//对代理对象的引用.
	private List aList;

	/**
	 * 构造器。
	 * @param list 代理对象
	 */
	public MyInvocationHandle(Object list) {
		this.aList = (List) list;
	}

	/**
	 * InvocationHandler的方法实现
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		
		//方法前调用,插入一段消息
		System.out.println("before : "+method.getName());
		
		//调用方法.
		Object object = method.invoke(aList, args);
		
		//方法后调用,插入一段消息
		System.out.println("after : "+method.getName());
		
		return object;
	}



	public static void main(String[] args) {
		//需要代理一个ArrayList对象,因此按照API构造一个Proxy对象
		//,同时也初始化了处理Proxy的MyInvocationHandle对象
		Class clz = ArrayList.class;
		Object proxyed_Object = Proxy.newProxyInstance(clz.getClassLoader(),
				clz.getInterfaces(), new MyInvocationHandle(new ArrayList(10)));
		
//TEST1:查看一下代理生成类的接口???
//		Class<!---->[] itfs = proxyed_Object.getClass().getInterfaces();
//		for (int i = 0; i < itfs.length; i++) {
//			System.out.println(itfs[i].getName());
//		}
		
		//注意!这里操作的是代理类!
		List list = (List)proxyed_Object;
		list.add(Integer.valueOf(10));
		
//TEST2:输出一下list的大小,确认add方法被调用		
//		System.out.println(list.size());
	}
}

输出如下:

before : add
after : add

如果将TEST2段代码去掉注释,可以看到如下输出:

before : add
after : add
before : size
after : size
1

证明add方法确实被调用了。


 三。代理模式的结构图(UML+时序图)

通过UML图可以看到代理类和被代理实际对象实现同一接口/或者一个抽象类,因此外部调用Subject,是感觉不到代理类的存在。

 

问题出现了:上面的测试代码中,被代理ArrayList对象,并未与调用者MyInvocationHandle实现同样的接口 。那是怎么实现代理模式的呢?

看Proxy类的文档,写到:

   /**
     * Returns an instance of a proxy class for the specified interfaces
     * that dispatches method invocations to the specified invocation
     * handler.  This method is equivalent to:
     * 
     *     Proxy.getProxyClass(loader, interfaces).
     *         getConstructor(new Class[] { InvocationHandler.class }).
     *         newInstance(new Object[] { handler });
     * 
* *

Proxy.newProxyInstance throws * IllegalArgumentException for the same reasons that * Proxy.getProxyClass does. * * @param loader the class loader to define the proxy class * @param interfaces the list of interfaces for the proxy class * to implement * @param h the invocation handler to dispatch method invocations to * @return a proxy instance with the specified invocation handler of a * proxy class that is defined by the specified class loader * and that implements the specified interfaces * @throws IllegalArgumentException if any of the restrictions on the * parameters that may be passed to getProxyClass * are violated * @throws NullPointerException if the interfaces array * argument or any of its elements are null, or * if the invocation handler, h, is * null */

返回一个实现指定接口的代理类实例,并绑定方法调用到一个指定的invocation handler.

如果将TEST1段注释去掉,可以看到这个代理对象实现了如下接口:

 java.util.List    java.util.RandomAccess     java.lang.Cloneable      java.io.Serializable

 

并且Proxy.newProxyInstance等同于

     *     Proxy.getProxyClass(loader, interfaces).
     *         getConstructor(new Class[] { InvocationHandler.class }).
     *         newInstance(new Object[] { handler });

这里是部分源码:

	    for (int i = 0; i < interfaces.length; i++) {
		int flags = interfaces[i].getModifiers();
		if (!Modifier.isPublic(flags)) {
		    String name = interfaces[i].getName();
		    int n = name.lastIndexOf('.');
		    String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
		    if (proxyPkg == null) {
			proxyPkg = pkg;
		    } else if (!pkg.equals(proxyPkg)) {
			throw new IllegalArgumentException(
			    "non-public interfaces from different packages");
		    }
		}
	    }

 

通过时序图可以看到,外部Client和代理类打交道,而代理类在调用实际对象时可以增加一些有益的操作。

分享到:
评论

相关推荐

    apache开源项目源码commons-proxy-1.0-src(全部高质量代理模式proxy的java源程序)

    java.proxy,代理模式源码,设计模式,apache开源项目源码commons-proxy-1.0-src 各种代理模式操作的工具类源码以及代理模式案例源码,你会从中得到意想不到的效果! apache开源组织开发的开源项目源码,其优良的代码...

    详解设计模式中的proxy代理模式及在Java程序中的实现

    Proxy模式是设计模式中的一种,它提供了一种对对象访问的控制手段,使得在不修改原有对象的基础上,可以通过代理对象来扩展或增强原有对象的功能。在Java编程中,Proxy模式的应用非常广泛,尤其是在处理远程调用、...

    java实现Proxy例子

    我自己用eclipse写的java代码,可以直接用eclipse导入,也可以直接用java -jar proxy_sample.jar执行 代码量很小,尽量通过注释进行说明 本例实现了InvocationHandler...在研究代理模式(Proxy模式)的朋友可以交流一下

    proxy.rar java三种代理模式源码

    总结来说,"proxy.rar"压缩包提供了Java编程中三种代理模式的源代码实例,通过学习这些代码,开发者可以深入理解代理模式的原理和实现,同时掌握泛型在实际项目中的应用。对于提高代码的可扩展性和可维护性,这些都...

    Java设计模式-代理模式例子

    在这个“Java设计模式-代理模式例子”中,我们将深入探讨代理模式的概念、实现方式以及它在实际开发中的应用。 代理模式的核心思想是为一个对象提供一个替身,这个替身即代理对象,代理对象控制对原对象的访问。在...

    java模式设计-代理模式之动态代理.ppt

    在Java中,动态代理是代理模式的一种实现方式,它允许我们在运行时创建代理对象,这种方式比静态代理更加灵活。动态代理在JDK 1.3及以后的版本中得到了支持,主要涉及到三个核心类:`Proxy`、`InvocationHandler`和`...

    java Proxy 动态代理

    在Java中,动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类是用于创建一个代理对象,而InvocationHandler接口则定义了代理对象调用方法时的行为。 1. **...

    Java Spring代理模式AOP-IOC分析

    Java中有两种方式来实现动态代理,一种是使用JDK中的Proxy类,另一种是使用CGLIB库。使用JDK中的Proxy类,可以生成代理对象,并将其绑定到原始对象上。使用CGLIB库,可以生成代理对象,并将其绑定到原始对象上,同时...

    21-Proxy_01-第十二模式.mp4

    Java设计模式精讲-代理模式

    Java代理模式Java动态代理

    ### Java代理模式与Java动态代理详解 #### 一、代理模式概述 代理模式是一种软件设计模式,它在客户端和目标对象之间提供了一种间接层。这种模式的主要目的是控制客户端对目标对象的访问,并且可以在不修改原有...

    代理模式java代码 Proxy(4)

    在Java中,代理模式可以通过多种方式实现,包括静态代理和动态代理。 在提供的文件列表中,我们可以看到以下几个关键类: 1. `ProxyDisplay`:这个名字暗示了它可能是代理模式中的代理类,用于代表或代替某个实际...

    JAVA设计模式例程-代理模式

    在这个"JAVA设计模式例程-代理模式"的压缩包中,我们可以深入学习如何在Java中实现这一模式。 1. **代理模式的基本概念** 代理模式的核心思想是为一个目标对象创建一个代理对象,代理对象在客户端和目标对象之间起...

    代理模式java代码 Proxy(1)

    在Java中实现代理模式,通常有两种方式:静态代理和动态代理。 首先,我们来看静态代理。静态代理是通过创建一个代理类来实现对目标对象的代理,这个代理类和目标类具有相同的接口,代理类在调用目标对象方法时可以...

    Proxy 模式学习代码

    1. **静态代理**:在静态代理中,我们需要为每个真实对象创建一个代理对象,并在代理类中实现与真实对象相同的方法。这样,当客户端调用代理对象的方法时,实际上会调用到代理类中相应的方法,从而可以添加额外的...

    用Java实现的代理模式之动态代理

    在Java中,代理模式有静态代理和动态代理两种实现方式。本篇将重点讨论"动态代理",这是一种在运行时创建代理对象的技术,使得我们可以在程序运行过程中,根据需要动态地生成具有额外功能的代理类。 动态代理主要由...

    代理模式 proxy-learn.rar

    在Java中,代理模式有静态代理和动态代理两种主要实现方式,它们都是为了在客户端与目标对象之间插入一个代理对象,从而实现对目标对象的间接访问。 ### 静态代理 静态代理是程序员手动创建代理类并实现相同接口的...

    设计模式-代理模式-java

    在Java中,代理模式可以通过多种方式实现,包括静态代理、动态代理(JDK动态代理和CGLIB动态代理)等。 **静态代理** 静态代理是最基础的代理形式,需要手动创建一个代理类,该类继承或实现与目标类相同的接口,并...

    java模式设计-献给喜欢java的人

    2. 结构型模式:如代理模式(Proxy)、适配器模式(Adapter)、装饰器模式(Decorator)、桥接模式(Bridge)、组合模式(Composite)、外观模式(Facade)和享元模式(Flyweight)。这些模式主要处理对象之间的关系...

    java中的三种代理模式

    在Java编程中,代理模式是一种常用的面向对象设计模式,它允许我们为一个对象提供一个代理以控制对该对象的访问。代理模式通常用于增加额外的功能,如日志、权限检查等,或者为了创建虚拟代理以提高性能。以下是Java...

    Java动态代理实现 Proxy InvocationHandler

    总结来说,Java动态代理通过`Proxy`和`InvocationHandler`提供了灵活的代码扩展机制,可以在运行时为对象创建代理,实现在不修改原有代码的基础上添加额外功能。这在处理需要拦截和增强的对象时非常有用,例如日志...

Global site tag (gtag.js) - Google Analytics