您的位置:首页 > 编程语言 > Java开发

设计模式学习笔记---代理模式Proxy(Java版)

2015-03-02 22:30 851 查看
一、场景

明星的经纪人

二、实质

通过代理控制对对象的访问。可以详细控制访问某个(某类)对象的方法,在调用这个方法之前做前置处理,调用这个方法后做后置处理。

AOP的核心实现机制。

三、角色

抽象角色--定义代理角色和真实角色的公共对外方法

真实角色--实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。关注真正的业务逻辑。(相当于明星)

代理角色--实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法实现抽象方法,并可以附加自己的操作。将统一的流程控制放到代理角色中处理。

(相当于经纪人)

四、分类

静态代理(静态定义代理类)

动态代理(动态生成代理类)

JDK自带的动态代理

javassist字节码操作库实现

CGIB

ASM

五、示例

1、静态代理



案例一

package com.lgd.proxy;

public interface Star {
	void confer();//面谈
	void signContract();//签合同
	void bookTicket();//订票
	void sing();//唱歌
	void collectMoney();//收钱
}


package com.lgd.proxy;

public class RealStar implements Star{

	@Override
	public void confer() {
		System.out.println("realstar.confer()");		
	}

	@Override
	public void signContract() {
		System.out.println("realstar.signContract()");		
	}

	@Override
	public void bookTicket() {
		System.out.println("realstar.bookTicket()");		
	}

	@Override
	public void sing() {
		System.out.println("realstar(@@@beyond@@@).sing()");
	}

	@Override
	public void collectMoney() {
		System.out.println("realstar.collectMoney()");
	}
	
}


package com.lgd.proxy;

public class ProxyStar implements Star{
	private Star star;
	
	public ProxyStar(Star star) {
		super();
		this.star = star;
	}

	@Override
	public void confer() {
		System.out.println("proxystar.confer()");
	}

	@Override
	public void signContract() {
		System.out.println("proxystar.signContract()");
	}

	@Override
	public void bookTicket() {
		System.out.println("proxystar.bookTicket()");		
	}

	@Override
	public void sing() {
		star.sing();
	}

	@Override
	public void collectMoney() {
		System.out.println("proxystar.collectMoney()");
	}

}


package com.lgd.proxy;

public class Client {
	public static void main(String[] args) {
		Star realStar = new RealStar();
		Star proxyStar = new ProxyStar(realStar);
		proxyStar.confer();
		proxyStar.signContract();
		proxyStar.bookTicket();
		proxyStar.sing();
		proxyStar.collectMoney();
	}
}


运行结果:

proxystar.confer()

proxystar.signContract()

proxystar.bookTicket()

realstar(@@@beyond@@@).sing()

proxystar.collectMoney()

案例二

package Thread;

/**
 * 静态代理设计模式
 * 1、真实角色
 * 2、代理角色  持有真实角色的引用
 * 3、二者要实现相同的接口
 */
public class Demo02 {
	public static void main(String[] args) {
		//创建真实角色
		You you = new You();
		//创建代理角色 + 加入真实角色的引用
		WeddingCompany company = new WeddingCompany(you);//
		//执行任务
		company.marry();	
	}	
}

//接口
interface Marry
{
	public abstract void marry();
}

//真实角色
class You implements Marry{
	@Override
	public void marry() {
		System.out.println("今天你要嫁给我。。。");
	}	
}

//代理角色
class WeddingCompany implements Marry{
	private Marry you;
	
	public WeddingCompany() {
	}
	public WeddingCompany(Marry you) {
		super();
		this.you = you;//使用真实角色对其初始化
	}
	private void before(){
		System.out.println("婚前布置会场");
	}	
	
	private void after(){
		System.out.println("婚后打扫清洁");
	}	
	
	@Override
	public void marry() {
		before();
		you.marry();
		after();
	}	
}


运行结果:

婚前布置会场

今天你要嫁给我。。。

婚后打扫清洁

2、动态代理(dynamic proxy)

JDK自带的动态代理

java.lang.reflect.Proxy 作用:动态生成代理类和对象。

java.lang.reflect.InvocationHandler(处理器接口) 通过invoke方法对真实角色的代理访问。每次通过Proxy生成代理类对象时都要制定对应的处理器对象。

package com.lgd.dynamicproxy;

public interface Star {
	void confer();//面谈
	void signContract();//签合同
	void bookTicket();//订票
	void sing();//唱歌
	void collectMoney();//收钱
}


package com.lgd.dynamicproxy;

public class RealStar implements Star{

	@Override
	public void confer() {
		System.out.println("realstar.confer()");		
	}

	@Override
	public void signContract() {
		System.out.println("realstar.signContract()");		
	}

	@Override
	public void bookTicket() {
		System.out.println("realstar.bookTicket()");		
	}

	@Override
	public void sing() {
		System.out.println("realstar(@@@beyond@@@).sing()");
	}

	@Override
	public void collectMoney() {
		System.out.println("realstar.collectMoney()");
	}
	
}


package com.lgd.dynamicproxy;

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

public class StarHandler implements InvocationHandler{

	Star realStar;
	
	public StarHandler(Star realStar) {
		super();
		this.realStar = realStar;
	}

	/**
	 * 核心方法    做统一的流程控制
	 * 代理类的任何方法都来这里报到。
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object object = null;
		System.out.println("真正的方法执行前!");
		System.out.println("面谈,签合同,预付款,订机票");
		if(method.getName().equals("sing"))
		{
			object = method.invoke(realStar, args);
		}
		System.out.println("真正的方法执行后!");
		System.out.println("收钱");
		return object;
	}

}


package com.lgd.dynamicproxy;

import java.lang.reflect.Proxy;

public class Client {
	public static void main(String[] args) {
		Star realStar = new RealStar();
		StarHandler handler = new StarHandler(realStar);
		
		Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), 
				new Class[]{Star.class}, handler);
		//proxy.bookTicket();
		proxy.sing();
	}
}


运行结果:

真正的方法执行前!

面谈,签合同,预付款,订机票

realstar(@@@beyond@@@).sing()

真正的方法执行后!

收钱

六、应用场景

安全代理:屏蔽对真实角色的直接访问。

远程代理:通过代理类处理远程方法调用(RMI)。

延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: