什么是代理模式:
代理模式类似于买房中介,买房的一些繁杂过程你可以找人帮你代理,你直接付钱入住就行,也类是于明星的经纪人,什么签合同,免谈之类的事情就它让你搞定,你只需要演戏就行。
代理的架构如下:
其中代理,必须要有一个引用指向真实类。
代理模式应用场景:
安全代理:屏蔽对真是角色的访问
远程代理:通过代理类处理远程方法调用
延迟加载:先加载轻量级的代理对象,真正需要的时候,再加载真实对象
代理模式有静态代理和动态代理,动态代理有如下的实现方法:
1.JDK自带的动态代理,常用
2.javaassist字节码操作库实现
3.CGLIB
4.ASM
举例子最能说明问题:
1.静态代理:
首先,我们来定义一个抽象接口
/**
* 抽线接口
* @author liuxg
* @date 2016年5月25日 下午4:34:40
*/
public interface Star {
void meeting() ; //开会,可以让代理执行
void bookTicket(); //订机票可以让代理执行
void collectMoney(); //收钱,可以让代理执行
void acting(); //演戏只能自己执行
}
再定义一个真实类实现抽象接口
/**
* 真是明星
*
* @author liuxg
* @date 2016年5月25日 下午5:01:35
*/
public class RealStar implements Star {
@Override
public void meeting() {
System.out.println("开会");
}
@Override
public void bookTicket() {
System.out.println("订票");
}
@Override
public void collectMoney() {
System.out.println("收钱");
}
@Override
public void acting() {
System.out.println("演戏");
}
}
再定义一个代理类,来代理我们的realstar类,这个类需要实现抽象接口,也要有一个可以引用realstar的指针
/**
* 代理类
* @author liuxg
* @date 2016年5月25日 下午5:06:03
*/
public class ProxyStar implements Star{
private RealStar realStar;
public ProxyStar(RealStar realStar) {
this.realStar = realStar;
}
@Override
public void meeting() {
System.out.println("开会");
}
@Override
public void bookTicket() {
System.out.println("订票");
}
@Override
public void collectMoney() {
System.out.println("收钱");
}
@Override
public void acting() {//aop编程的原理
System.out.println("代理类做一些前置操作");
realStar.acting();
System.out.println("代理类做一些后置操作");
}
}
我们写测试类来测试
public class Client01 {
public static void main(String[] args) {
Star role = new ProxyStar(new RealStar());
role.meeting();
role.bookTicket();
role.collectMoney();
role.acting();
}
}
2.动态代理举个例子
首先抽象接口Star 和真实的类RealStar都是一样,但是代理类ProxyStar,我们通过JDK自带的代理来动态生成,我们来定义一个代理类处理器
/**
* 代理类生成器
* @author liuxg
* @date 2016年5月25日 下午5:23:51
*/
public class ProxyHandler implements InvocationHandler{
RealStar realStar;
public ProxyHandler(RealStar realStar) {
this.realStar = realStar;
}
/**
* 任何调用真实角色的方法都会到这里来
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("方法操作之前");
method.invoke(realStar, args);
System.out.println("方法操作之后");
return null;
}
}
然后在客户端,我们就可以这样子动态生成代理并调用了
public class Client01 {
public static void main(String[] args) {
ProxyHandler hander = new ProxyHandler(new RealStar());
Star star = (Star) Proxy.newProxyInstance(Client01.class.getClassLoader(), new Class[]{Star.class}, hander); //动态生成代理类
star.acting();
}
}