动态代理模式

1.概念

代理模式:为另一个对象提供一个替身或占位符以访问对象。

2.分析过程

1.RMI

RMI提供了客户辅助对象和服务辅助对象,为客户辅助对象创建和服务对象相同的方法。RMI的好处在于你不必亲自写网络或i/o代码。客户程序调用远程方法就和在运行在客户自己的本地jvm对象进行正常方法调用一样。

2.制作远程服务

制作远程接口。定义出让客户远程调用的方法。stub和实际的服务都实现此接口。

制作远程的实现。做实际工作的,客户端真正想要调用的方法的对象。

利用rmic产生额stubskeleton。这就是客户和服务的辅助类,不需要自己创建这些类。

启动RMIregistry。客户可以从中查到代理的位置。

开始远程服务。你的服务实现类会去实例化一个服务的实例。

3.代理有好多,着重讲动态代理

javajava.lang.reflect包有自己的代理支持,利用这个包你可以运行时动态地创建一个代理类,实现一个或多个接口,并将方法的调用转发到你所指定的类。因为实际的代理类是在运行时创建的,我们称为这个java技术为:动态代理。

java已经为你创建了Proxy类,所以你需要有办法来告诉Proxy类你要做什么。你不能像以前一样把代码放在Proxy类中,因为Proxy不是你直接 实现的。既然这样的代码不能放在Proxy类中,那么要放在那里?放在InvocationHandler中。InvocationHandle的工作是相应代理的如何调用。你可以把InvocationHandler想成是代理收到的方法调用后,请求做实际工作的需要。

4.动态调用的过程:

不管代理被调用的是何种方法,处理器被调用的一定是invoke()方法。

如何工作:

 1.假设proxysetHotOrNotRating()方法被调用

  proxy.setsetHotOrNotRating(9);

  2.proxy会接着调用InvocationHandlerinvoke()方法。

 invoke(Objec proxy,Method method , Object[]args)

3.hadler决定要如何处置这个请求,可能会转发给RealSubjectHandler到底是如何决定的呢?

--->return   method.invoke(person, args);

3.举例源码

//对象村的配对
/*
PersonBean ,允许设置或取得一个人的信息。
*/
public interface PersonBean{
	String getName();
	String getGender();
	String getIntertest();
	int getHotOrNotRating();
	
	void setName(String name);
	void setGender(String gender);
	void setInterests(String interests);
	void setHotOrNotRating(int rating);
}
/*
PersonBean实现
*/
public class PersonBeanImpl implements PersonBean{
	String name;
	String gender;
	String interests;
	int rating;
	int ratingCount = 0;
	
	public String getName(){
		return name;
	}
	public String getGender(){
		return interests;
	}
	public int getHotOrNotRating(){
		if(ratingCount == 0 ) return 0;
		return (rating/ratingCount);
	}
	
}
//为PersonBean创建代理
/*
我们有一些问题要修正:顾客不可以改变自己的HotOrNot评分,也不可以改变其顾客的个人信息。要修正这些问题,你必须创建两个代理:
一个访问你自己的PersonBean对象,另一个访问另一个顾客的PersonBean对象。这样,代理就可以控制在每一种情况下允许哪一种请求。

*/
/*
创建步骤:
1.创建两个InvocationHandler,这个实现了代理的行为。
2.写代码创建动态代理。
3.利用适当的代理包装任何PersonBean对象
什么是InvocationHandler呢?-->当代理的方法被调用时,代理就会把这个调用转发给InvocationHandler,但是这并不是通过调用InvocationHandler
的相应方法做到的。
*/
public class OwnerInvocationHandler implements InvocationHandler{
	PersonBean person;
	public OwnerInvocationHandler(PersonBean person){
		this.person = person;
		
	}
	public Object invoke(Object proxy ,Method method , Object [] args){
		try{
			if(method.getName().startWith("get")){
				return method.invoke(person,args);
			}else if (method.getName().equals("setHotOrNotRating")){
				throw new IllegalAccessException();
			}else if(method.getName().startWith("set")){
				return method.invoke(person,args);
			}catch(InvocationTargetException e){
				e.printStackTrace();
			}
				
		}
		return null;//如果调用其它的方法,一律不理,返回null
	}
}
//创建proxy类并实例化proxy对象
PersonBean getOwnerProxy(PersonBean person){
	return (PersonBean) proxy.newProxyInstance(person.getClass().getClassLoader(),
												person.getClass().getInterfaces(),
												new OwnerInvocationHandler(person));
												
	
}
//测试配对对象
public class MatchMakingTestDrive{
	//这里有实例变量
	public static void main(String[] args){
		MatchMakingTestDrive test = new MatchMakingTestDrive();
		test.drive();
	}
	public MatchMakingTestDrive(){
		initializeDatabase();
	}
	public void drive(){
		PersonBean joe = getPersonFromDatabase("joe javabean");//从数据库取出一个人
		PersonBean ownerProxy = getOwnerProxy(joe);//然后创建一个拥有者代理
		System.out.println("name is" +ownerProxy.getName());//调用get
		ownerProxy.setInterests("bowling");//调用set
		try{
			ownerProxy.setHotOrNotRating(10);//试着改变评分,行不通
		}catch(Exception e){
			....
		}
		PersonBean nonOwnerProxy = getNonOwerProxy(joe);//创建一个非拥有代理
		//set方法行不通
		
		
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值