代理模式Proxy

1. 定义
为其他对象提供一种代理以控制这个对象的访问。

 

2. 结构图

 


Proxy:代理对象。通常具有如下功能。
     实现与具体的目标对象一样的接口,这样就可以使用代理来代替具体的目标对象。
     保存一个指向具体目标对象的引用,可以在需要的时候调用具体的目标对象。
     可以控制对具体目标对象的访问,并可以负责创建和删除它。
Subject:目标接口,定义代理和具体目标对象的接口,这样就可以在任何使用具体目标对象的地方使用代理对象。
RealSubject:具体的目标对象,真正实现目标接口要求的功能。

 

3. 本质
代理模式的本质:控制对象访问。 

 

4. Code Demo

Subject.java

package org.fool.proxy;

public interface Subject {
	public void request();
}

 

RealSubject.java

package org.fool.proxy;

public class RealSubject implements Subject {

	@Override
	public void request() {
		System.out.println("From real subject.");
	}

}

 

ProxySubject.java

package org.fool.proxy;

public class ProxySubject implements Subject {
	
	private RealSubject realSubject;	// 代理角色所完成的事情

	@Override
	public void request() {
		this.preRequest();	// 在真实角色操作之后所附加的操作(非必须)
		
		if(null == realSubject) {
			realSubject = new RealSubject();
		}
		
		realSubject.request();	// 真实角色所完成的事情
		
		this.postRequest();	// 在真实角色之后所附加的操作(非必须)
	}
	
	private void preRequest() {
		System.out.println("pre request");
	}
	
	private void postRequest() {
		System.out.println("post request");
	}

}

 

Client.java

package org.fool.proxy;

public class Client {
	public static void main(String[] args) {
		Subject subject = new ProxySubject();
		
		subject.request();
	}
}

 

5. 动态代理

Java对代理模式提供了内建的支持,在java.lang.reflect包下面,提供了一个Proxy的类和一个InvocationHandler的接口。
通常把前面自己实现的代理模式称为Java的静态代理。这种实现方式有一个较大的缺点,就是如果Subject接口发生变化,那么代理类和具体的目标实现都要变化,不是很灵活。而使用Java内建的对代理模式支持的功能来实现则没有这个问题。
通常把使用Java内建的对代理模式支持的功能来实现的代理称为Java的动态代理。动态代理跟静态代理相比,明显的变化是:静态代理实现的时候,在Subject接口上定义很多的方法,代理类里面自然也要实现很多方法;而动态代理实现的时候,虽然Subject接口上定义了很多方法,但是动态代理类始终只有一个invoke方法。这样,当Subject接口发生变化的时候,动态代理的接口就不需要跟着变化了。
Java的动态代理目前只能代理接口,基本的实现是依靠Java的反射机制和动态生成class的技术,来动态生成被代理的接口的实现对象。
代理模式在客户和被客户访问的对象之间,引入了一定程度的间接性,客户是直接使用代理,让代理来与被访问的对象进行交互。不同的代理类型,这种附加的间接性有不同的用途,也就具有不同的特点。

 

动态代理Demo

Subject.java

package org.fool.dynamicproxy;

public interface Subject {
	public void request();
}

 

RealSubject.java

package org.fool.dynamicproxy;

public class RealSubject implements Subject {

	@Override
	public void request() {
		System.out.println("From real subject...");
	}

}

 

DynamicSubject.java

package org.fool.dynamicproxy;

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

public class DynamicSubject implements InvocationHandler {

	private Object subject;

	public DynamicSubject(Object subject) {
		this.subject = subject;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		
		System.out.println("before calling: " + method);
		
		method.invoke(subject, args);
		
		System.out.println("after calling: " + method);
		
		return null;
	}

}

 

Client.java

package org.fool.dynamicproxy;

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

public class Client {
	public static void main(String[] args) {
		Subject realSubject = new RealSubject();

		InvocationHandler handler = new DynamicSubject(realSubject);

		Class<?> classType = handler.getClass();

		Subject subject = (Subject) Proxy.newProxyInstance(classType.getClassLoader(),
				realSubject.getClass().getInterfaces(), handler);

		subject.request();
	}
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值