代理模式
为什么要学习代理模式? 因为这就是SpringAOP的底层
代理模式的分类:
- 静态代理
- 动态代理
1.静态代理
角色分析:
- 抽象角色(租房):一般会使用接口或者抽象类来解决
- 真实角色(房东):被代理的角色
- 代理角色(中介):代理真实角色, 代理角色会做一些附属操作
- 客户(我):访问代理角色的人
-
接口:
public interface Rent { public void rent(); }
-
真实角色
public class Host implements Rent { public void rent() { System.out.println("包租婆出租屋"); } }
-
代理角色
public class Proxy implements Rent { private Host host; public Proxy() { } public Proxy(Host host) { this.host = host; } public void rent() { System.out.println("通过代理:"); see(); host.rent(); sign(); fee(); } public void see(){ System.out.println("中介带你看房"); } public void sign(){ System.out.println("签租赁合同"); } public void fee(){ System.out.println("收中介费"); } }
-
客户
public class Client { public static void main(String[] args) { Host host = new Host(); Proxy proxy = new Proxy(host); proxy.rent(); } }
代理模式的好处:
- 可以使得真实角色的操作更加纯粹,不用去关注一下公共的业务
- 公共业务交给了代理角色,实现了业务的分工
- 方便公共业务的集中管理
缺点:
- 一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率会变低
2.动态代理
- 动态代理和静态代理角色一样
- 动态代理的代理类是动态生成的,不是我们自己写好的
- 动态代理的两大类: 基于接口的动态代理, 基于类的动态代理
- 基于接口 -- JDK动态代理
- 基于类: cglib
- java字节码实现: javassist
需要了解两个类: Proxy(代理) , InvocationHandler(调用处理程序)
动态代理的使用
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Object target;
public void setTarget(Object target) {
this.target = target;
}
//生产得到代理类
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
//处理代理实例并返回结果
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
//动态代理的本质,就是使用反射机制
Object result = method.invoke(target, args);
return null;
}
public void log(String msg){
System.out.println("执行力"+msg+"方法");
}
}
public class Client {
public static void main(String[] args) {
UserServiceImpl service = new UserServiceImpl();
ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler();
proxyInvocationHandler.setTarget(service);
UserService proxy = (UserService) proxyInvocationHandler.getProxy();
proxy.add();
proxy.update();
proxy.query();
proxy.delete();
}
}
好处:
- 一个动态代理的类代理一个接口,对应于一类业务
- 实现了同一个接口时,一个动态代理的类可以代理多个类