Java代理

代理模式是Java中使用十分广泛的一种设计模式,代理模式就是客户端(调用者、访问者)不直接的调用(访问)实际对象,而是通过访问代理对象间接的去访问实际对象。

理解代理模式前先了解几个概念:

  1. 抽象角色:定义真实角色和代理角色都要遵守的规则
  2. 真实角色:实现抽象角色,提供真实业务处理逻辑
  3. 代理角色:需要实现抽象角色,通过真实角色的业务逻辑,来实现客户端的访问。。。
代理模式的分类:
  1. 静态代理
  2. 动态代理
    以前在网上看到过用老板和助理来举例代理模式的:
public class Boss{}
public class Assistant{}
一、静态代理模式

设置这样一个场景:有一个人A要见这个老板,和老板谈谈人生、聊聊理想;
在这个场景中 A就是客户端(调用者、访问者);老板就是真实角色(A真正要谈人生聊理想的对象);助理就是代理角色(老板不是想见就见的,需要通过助理预约)
使用静态代理,我们先要提取一个对外接口,真实对象和代理对象都实现

public interface ProxyInterface{ void talk();  //谈人生,聊理想}

public class Boss implements ProxyInterface {
	@Override
	public void talk(){
		//老板实现谈人生聊理想的逻辑
	}
}

public class Assistant implements ProxyInterface {
	private ProxyInterface proxyInterface;	//助理需要持有老板对象
	public Assistant(ProxyInterface proxyInterface){
		this.proxyInterface = proxyInterfac;
	}
	@Override
	public void talk(){
		proxInterface.talk(); //助理通过老板对象也可以谈理想
	}
}

当访问者要和老板谈理想时,就可以这样操作

	//不直接访问老板,而是通过助理
	ProxyInterface proxy = new Asstanct(new Boss());
	proxy.talk();//这里的代理(助理)就代表了老板,不要拘泥于显示中一定要和老板面对面

这样举例很多人会疑惑,还不如直接通过老板对象简单,在扩展一下,老板是很忙的,要和老板聊天前,总要看看老板的日程安排吧,然后找个空闲时间安排聊天,安排好后还得找个地方才能聊天吧,聊完后还需要有一些后续的工作等,这一整套流程除了老板具体的聊天内容,其余的都是套路性质的,不需要老板亲自处理,这个时候代理对象就可以代劳了。

public class Assistant implements ProxyInterface {
	...
	@Override
	public void talk(){
		//1.看看老板什么时候有时间,安排空余时间
		//2.安排地点
		proxyInterface.talk();
		//3.后续工作
	}
}
想这样实现,老板(真实角色)的功能是不是更纯粹了呢,很多时候不需要修改源代码,只需要代理对象就能扩展业务逻辑;
其实可以在扩展一下,公司有多个老板,但助理就一个,助理需要代理更多的老板了,该怎么处理
二、动态代理

当需要代理的对象多了,代理对象需要持有的真实对象就会很多,而且没有需要要代理的对象都需要实现我们定义的接口,一旦接口有该多,实现对象都需要该多。会很冗余且不利于解耦,此时就可以使用动态代理:
动态代理:静态代理中,代理类是我们手写代码实现的,而在动态代理中,是借助程序自动实现。
还是用上面的例子举例:定义一个接口,定义真实对象类,动态代理类(使用JDK方式实现,依赖反射)

public interface ProxyInterface{ void talk(); }//接口
//真实角色类
public class Boss implements ProxyInterface {
	@Override
	public void talk();
}
//动态代理类
public class ProxyHandler implements InvocationHandler {
	private ProxyInterface pxyInterface;
	public ProxyDyna(ProxyInterface pxyInterface){
		this.pxyInterface = pxyInterface;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// 1 查看老板日程安排...
		// 2 ....
		Object res = method.invoke(pryInterface, args);
		// 3 ...
		return res;
	}
}

此时通过代理访问需要:

	ProxyInterface pxyInterface = new Boss();
	ProxyHandler handler = new ProxyHanlder(pxyInterface);
	//创建动态代理对象
	ProxyInterface proxy = (ProxyInterface).newProxyInstance(x.getClassLoader(),new Class[]{ProxyInterface.class},handler);
	//创建的proxy 对象, 是实现了代理接口的,可以调用接口中的所有方法
	proxy.talk();
	//当创建的动态代理对象调用接口定义的任意方法时,会直接进入动态代理类ProxyHandler 中的 invoke(...)方法中
	// 使用method.invoke(pryInterface,args); 就是调用真实角色的 原方法
	//我们可以在调用前后添加业务处理,例如 重写方法中 1. 查查日常安排 等
	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值