代理模式

代理模式:通过代理,控制对对象的访问。

它的设计思路是:定义一个抽象角色,让代理角色和真实角色分别去实现它。

代理模式分为静态代理和动态代理。

静态代理:歌星接口(SingerStar),一个歌星(Singer),歌星对应的代理(ProxyStar)。歌星和代理实现歌星接口里的sing()方法,代理ProxyStar在sing()中调用Singer.sing()完成真是的动作唱歌,在Singer.sing()前后加入处理。

/**
 * 歌星接口
 * @author lenovo
 *
 */
public interface SingStar {
	
	public void sing();
	
}

/**
 * XX歌星
 * @author lenovo
 *
 */
public class Singer implements SingStar {
	
	private String song; 
	
	public Singer ( ) {
	}
	
	public Singer (String song) {
		this.song = song;
	}
	
	@Override
	public void sing() {
		System.out.println("歌手唱歌"+song);
	}

}

/**
 * XX歌星代理
 * @author lenovo
 *
 */
public class ProxyStar implements SingStar {
	
	/**
	 * 真实角色
	 */
	private SingStar realStar;
	
	public ProxyStar (SingStar realStar) {
		this.realStar = realStar;
	}
	
	@Override
	public void sing() {
		System.out.println("唱歌之前的谈判...");
		this.realStar.sing();
		System.out.println("唱完歌后的事务处理...");
	}

}

/**
 * 测试
 * @author lenovo
 *
 */
public class Client {

	public static void main(String[] args) {
		Singer singer = new Singer("下雪啦");
		ProxyStar proxyStar = new ProxyStar(singer);
		proxyStar.sing();
	}

}

运行结果:

唱歌之前的谈判...
歌手唱歌下雪啦
唱完歌后的事务处理...
 

动态代理:与静态代理相比建,动态代理的代理类是动态生成的,可以根据不同的接口生成不同的代理类,适用范围更加广泛。

/**
 * 歌星接口
 * @author lenovo
 *
 */
public interface SingStar {
	
	public void sing();
	
}

/**
 * XX歌星
 * @author lenovo
 *
 */
public class Singer implements SingStar {
	
	private String song; 
	
	public Singer ( ) {
	}
	
	public Singer (String song) {
		this.song = song;
	}
	
	@Override
	public void sing() {
		System.out.println("歌手唱歌"+song);
	}

}

/**
 * 舞星接口
 * @author lenovo
 *
 */
public interface DanceStar {
	
	public void dance (String name);
	
}

/**
 * XX舞星
 * @author lenovo
 *
 */
public class Dancer implements DanceStar {

	@Override
	public void dance(String name ) {
		System.out.println("舞星开始跳舞:" +name);
	}

}

/**
 * 生成动态代理类
 * @author lenovo
 *
 */
public class DynamicProxy {
	
	/**
	 * @param realObj 需要被代码的对象
	 * @return 生成的代理对象
	 * 使用final的原因:匿名内部类中使用了外部参数,不允许修改外部参数
	 */
	public Object getDynamicProxy(final Object realObj){
		
		return Proxy.newProxyInstance(realObj.getClass().getClassLoader(), 
				realObj.getClass().getInterfaces(), 
				new InvocationHandler() {
					
					@Override
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {
						if (("sing").equals(method.getName())) {
							System.out.println("代理谈价钱安排唱歌");
							method.invoke(realObj, args);
							System.out.println("代理在明星唱完歌后收钱");
						}
						if (("dance").equals(method.getName())) {
							System.out.println("代理谈价钱安排跳舞");
							method.invoke(realObj, args);
							System.out.println("代理在明星跳舞后收钱");
						}
						return null;
					}
				});
	}
}

/**
 * 测试
 * @author lenovo
 *
 */
public class Client {

	public static void main(String[] args) {
		Singer singer = new Singer("下雪啦");
		SingStar dynamicProxy = (SingStar) new DynamicProxy().getDynamicProxy(singer);
		dynamicProxy.sing();
		
		Dancer dancer = new Dancer();
		DanceStar danceStarProxy = (DanceStar) new DynamicProxy().getDynamicProxy(dancer);
		danceStarProxy.dance("Jump");
	}

}

运行结果:

代理谈价钱安排唱歌
歌手唱歌下雪啦
代理在明星唱完歌后收钱
代理谈价钱安排跳舞
舞星开始跳舞:Jump
代理在明星跳舞后收钱

JDK:JDK 实现动态代理需要实现类通过接口定义业务方法。意味着代理类只能控制到接口中的方法。

CGLIB:对于没有接口的类可采用CGLIB实现动态代码,但是因为采用的是继承,所以final修饰的类是不能动态代理的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值