`
xwood
  • 浏览: 102927 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Proxy模式

 
阅读更多
        Proxy模式是在客户端不方便或者不能直接访问业务逻辑时,通过第三方类提供访问的一种方法。这种代理除了提供业务逻辑访问之外,还可以增加业务功能,好比Decorator模式。通常情况下,它包含三个部分:
  • 1.Component:需要提供的业务功能抽象
  • 2.Proxy:代理类
  • 3.RealComponent:真实需要提供的业务功能


UML图:


        以下是归纳的经常使用代理的地方:
  • 远程(Remote)代理:为一个位于不同的地址空间的对象提供代理,这个地址空间要么是用户不知道的,要么是没权限直接访问的。
  • 虚拟(Virtual)代理:根据需要创建一个资源消耗大的对象,使得此对象只在需要时才被真正创建,像输入输出流,数据库连接,网络TCP连接等。
  • Copy-on-Write代理:把Copy拖延到只有在需要Write的时候才采取行动。
  • 保护(Protect or Access)代理:控制一个对象的访问,如果需要,可以给不同的用户提供不同的访问权限。
  • Cache代理:为某一个目标操作结果提供临时的存储空间,以便多个客户端可以共享这些结果。
  • 防火墙代理:保护目标,不让恶意用户接近。
  • 分布式同步代理:使几个用户可以同时使用一个对象而没有冲突。
  • 智能引用:当一个对象被引用时,提供一些额外的操作,如计算,记录状态等。



        下面再谈一下Java的动态代理对对象代理的实现。这一块主要关注的API有java.lang.reflect.Proxy和java.lang.reflect.InvocationHandler两个。Proxy类生成代理对象的代理实例,但对代理对象的方法调用则主要是通过InvocationHandler.invoke利用反射机制实现的。下面是一个包含了简单AOP的例子。

1.ProxyFactory:Proxy对象的生成工厂
/**
 * 
 * @author xwood
 *
 * @param <T> 被代理类的接口类型
 */
public class ProxyFactory<T> {

	/**
	 * 利用Class提供的方法实现代理的实例化
	 * @param clzz 被代理类的接口类型(Class 对象)
	 * @param target 实际被代理的对象实体, 主要用于InvocationHandler.invoke方法实现方法反射
	 * @return
	 * @throws NoSuchMethodException
	 * @throws InvocationTargetException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	public T getProxyInstance(Class<T> clzz, Object target) throws NoSuchMethodException, 
			InvocationTargetException, IllegalAccessException, 
			InstantiationException{
		InvocationHandler handler = new ProxyInvocationHandler(target);
		Class<?> proxyClass = Proxy.getProxyClass(
				clzz.getClassLoader(), 
				new Class[]{clzz});
		@SuppressWarnings("unchecked")
		T proxy = (T)proxyClass.getConstructor(new Class[]{InvocationHandler.class})
								.newInstance(new Object[]{handler});
		return proxy;
	}
	
	/**
	 * 利用Class提供的方法实现代理的实例化
	 * @param clzz 被代理类的接口类型
	 * @param target 实际被代理的对象实体, 主要用于InvocationHandler.invoke方法实现方法反射
	 * @return
	 */
	public T getProxyInstance1(Class<T> clzz, Object target) {
		return (T)Proxy.newProxyInstance(clzz.getClassLoader(), 
						new Class[]{clzz}, 
						new ProxyInvocationHandler(target));
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ProxyFactory<IProxyTarget> factory = new ProxyFactory<IProxyTarget>();
		IProxyTarget proxy = null;
//		try {
//			proxy = factory.getProxyInstance(IProxyTarget.class);
//		} catch (NoSuchMethodException e) {
//			e.printStackTrace();
//		} catch (InvocationTargetException e) {
//			e.printStackTrace();
//		} catch (IllegalAccessException e) {
//			e.printStackTrace();
//		} catch (InstantiationException e) {
//			e.printStackTrace();
//		}
		
		proxy = factory.getProxyInstance1(IProxyTarget.class, new ProxyTargetImpl());

		if(proxy == null) return;
		
//		String reVal = (String)proxy.process(1);
//		System.out.println(reVal);
		proxy.process(1);
	}

}


2.IProxyTarget: 被代理类的接口定义
public interface IProxyTarget {
	
	public void process(int num);
	
}


3.ProxyTargetImpl: 实际的被代理对象
public class ProxyTargetImpl implements IProxyTarget {

	@Override
	public void process(int num) {
		System.out.println("--------- Now, Well Done! Boy.");
		//return String.valueOf(num);
	}

}


4.ProxyInvocationHandler: 具体代理方法的执行逻辑
public class ProxyInvocationHandler implements InvocationHandler {
	/**
	 * 被代理类型的实体对象
	 */
	private Object target;
	
	/**
	 * 仅有于需要复杂AOP时针对每次代理实现的Aspect对象
	 */
	private Aspect aspect;

	public ProxyInvocationHandler(Object target){
		this.target = target;
	}
	
	public ProxyInvocationHandler(Object target, Aspect aspect){
		this.target = target;
		this.aspect = aspect;
	}
	
	/**
	 * 实际代理运行时的主要方法。
	 * 代理对象在被调用时,将被调用方法、参数及代理对象本身传递给invoke方法,
	 * 在invoke方法内实现真正的方法调用。这类似于Decorator模式中主方法的调用。
	 * 在invoke方法内的实现可以与proxy或者target完全无关,甚至也可以不用method
	 * 等传递的参数,具体如何使用根据实际情况而定。
	 * 在返回值方面,如果被代理方法有返回值,则采用invoke方法的返回值;否则,
	 * 依然返回空。
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		return method.invoke(target, args);
		
		//如果需要AOP处理,则可以将具体实现交给aspect进行处理。
		//return aspect.processAspect(target, method, args);
		
		//如果需要返回值,则采用invoke方法的返回值。
		//return "123";
	}

}


5.Aspect: AOP的切面构建类
public class Aspect {

	private List<Advice> adviceMap;
	
	//TODO 生成你的adviceMap
	public void initiate(){
		
	}
	
	public Object processAspect(Object target, Method method, Object[] args) 
			throws IllegalAccessException, IllegalArgumentException, 
					InvocationTargetException{
		Iterator<Advice> it = adviceMap.iterator();
		Advice advice = null;
		while(it.hasNext()){
			advice = (Advice)it.next();
			advice.processAdvice(1);
		}
		Object obj = method.invoke(target, args);
		
		it = adviceMap.iterator();
		while(it.hasNext()){
			advice = (Advice)it.next();
			advice.processAdvice(2);
		}
		return obj;
	};
}


6.Advice: 具体AOP类型
public class Advice {

	/**
	 * 
	 * @param status: 1:before; 2:after;
	 */
	public void processAdvice(int status){
		
	};
}


        需要注意的一点就是Java的动态代理只能实现对接口的代理,所以要对某个对象进行代理,一定要提前定义好接口。
分享到:
评论

相关推荐

    Proxy 模式学习代码

    Proxy模式是一种设计模式,它允许我们为一个对象创建一个代理对象,这个代理对象在客户端和目标对象之间起到中介的作用。这种模式在软件工程中广泛应用,主要用于控制对真实对象的访问,提供额外的功能,如日志、...

    简单工厂模式,工厂方法模式,抽象工厂模式和Proxy模式

    到工厂方法到抽象工厂,这几种都带有“工厂”的模式,总是容易叫人迷糊,我仔细研究了下,然后用简单的例子做类比,列出了自己的通俗理解和比较,大部分是自己的体会,感觉理的比较清楚,末尾提了下Proxy模式。

    基于Proxy模式的分布式MySQL数据库中间件设计源码

    MySQL数据库中间件:基于C语言开发,包含59个文件,包括22个C源文件...该项目是一个分布式MySQL数据库中间件,采用Proxy模式设计,基于核心业务对象切分,旨在提供高效的数据库查询和处理能力,适用于分布式系统环境。

    从房屋买卖看 java proxy 模式

    标题中的“从房屋买卖看 java proxy 模式”暗示了我们将通过一个具体的场景来探讨 Java 中的代理(Proxy)模式。在软件设计中,代理模式是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。在...

    C++ Proxy模式

    Proxy模式是软件设计模式中的一个关键元素,属于结构型模式的一种。在C++中,Proxy模式主要用于为其他对象提供一种代理以控制对这个对象的访问。这种模式的核心思想是通过创建一个代理对象来充当目标对象的中介,...

    设计模式C++学习之代理模式(Proxy)

    代理模式是一种设计模式,它是结构型模式之一,主要用于在客户端和目标对象之间建立一个代理对象,以便控制对目标对象的访问。在C++中,代理模式可以用来为其他对象提供一种代理以控制对这个对象的访问,或者增加...

    设计模式之代理模式proxy.zip

    JDK动态代理基于接口实现,它要求目标对象必须实现至少一个接口,然后通过Proxy类和InvocationHandler接口来创建并控制代理对象。当我们调用代理对象的方法时,实际执行的是InvocationHandler的invoke方法,这样可以...

    Proxy代理模式经典实例(绝对OOP)

    在Java中,Proxy模式主要依赖于Java的动态代理机制,这通常涉及到`java.lang.reflect.Proxy`和`java.lang.reflect.InvocationHandler`两个核心接口。`Proxy`类用于生成代理对象,而`InvocationHandler`接口定义了...

    apache+tomcat负载均衡_proxy模式

    内附完整配置教程和修改后的apache的httpd.conf文件和tomcat的server.xml配置文件,包含test测试项目,不包含apache和tomcat安装文件。 本教程参考网上资料,本机测试成功,如有问题可以私信说明。

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

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

    Programming_Proxy_classic_code_delphi.rar_delphi Proxy_proxy_pro

    Proxy模式是一种设计模式,其主要目的是为其他对象提供一个代理以控制对这个对象的访问。在Delphi中,Proxy可以用于创建远程代理,使得客户端可以像操作本地对象一样操作远程服务。这种模式在分布式系统、数据访问...

    23种设计模式整理pdf

    Proxy 模式是一种结构型模式,用于提供一种访问对象的接口。Proxy 模式的优点是可以提供一种统一的访问对象的接口,减少了代码的耦合度。Proxy 模式的缺点是它可能会增加代码的复杂度。 7. Adapter 模式 Adapter ...

    二十三种设计模式【PDF版】

    设计模式之 Proxy(代理) 以 Jive 为例,剖析代理模式在用户级别授权机制上的应用 设计模式之 Facade(门面?) 可扩展的使用 JDBC针对不同的数据库编程,Facade提供了一种灵活的实现. 设计模式之 Composite(组合) ...

    设计模式1,FACADE模式,Adapter

    本文将深入探讨FACADE模式、Adapter模式以及Singleton和Proxy模式的基本概念、应用场景和关键要素。 首先,FACADE(外观)模式是一种接口型模式,它的主要作用是为复杂的子系统提供一个简单的接口,使得客户端无需...

    JavaScript设计模式与开发实践.pdf

    由浅入深地讲解了16个设计模式,包括 singleton模式、Factory模式、Abstract Factory模式、Builder模式、Prototype模式、Adapter模式、Bridge模式、Composite模式、Decorator模式、Flyweight模式、Proxy模式、Chain ...

    java实现Proxy例子

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

    设计模式的几个简单例子

    Proxy模式是一种行为型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。在提供的代码中,`ICar`接口定义了`MoveCar()`方法,它是所有汽车类需要遵循的行为规范。`ProxyCar`类是代理,实现了`ICar`接口,...

    设计模式原理与应用之结构型模式.pptx

    例如,远程对象访问、数据库连接池等场景都广泛使用了Proxy模式。 这些设计模式在软件开发中起着关键作用,它们提供了解决常见问题的标准方案,提高了代码的可读性、可维护性和可扩展性。理解并熟练运用这些模式,...

Global site tag (gtag.js) - Google Analytics