【Spring】静态、动态代理模式
原创
©著作权归作者所有:来自51CTO博客作者wx5cee84fb43fbb的原创作品,请联系作者获取转载授权,否则将追究法律责任
为什么要学习代理模式?
因为AOP的底层机制就是动态代理!
代理模式:
- 静态代理
- 动态代理
静态代理
静态代理角色分析
抽象角色 : 一般使用接口或者抽象类来实现 【租房这件事】
真实角色 : 被代理的角色 【房东】
代理角色 : 代理真实角色 ; 代理真实角色后 , 一般会做一些附属的操作 .【中介】
客户 : 使用代理角色来进行一些操作 .【需要租房的人】
静态代理的好处:
可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情 .
公共的业务由代理来完成 . 实现了业务的分工 ,
公共业务发生扩展时变得更加集中和方便 .
缺点 :
类多了 , 多了代理类 , 工作量变大了 . 开发效率降低 .代码量会翻倍,开发效率会变低。
静态代理的例子一:代码实现:
Rent . java 即抽象角色
//租房
public interface Rent {
public void rent();
}
Host . java 即真实角色
public class Host implements Rent{
public void rent() {
System.out.println("房东要出租房子");
}
}
Proxy . java 即代理角色
public class Proxy implements Rent{
private Host host;
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
public void rent() {
host.rent();
seeHouse();
hetong();
fare();
}
//看房
public void seeHouse(){
System.out.println("中介带你看房");
}
//收中介费
public void fare(){
System.out.println("收中介费");
}
//合同
public void hetong(){
System.out.println("签合同");
}
}
Client . java 即客户
public class Proxy implements Rent{
private Host host;
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
public void rent() {
host.rent();
seeHouse();
hetong();
fare();
}
//看房
public void seeHouse(){
System.out.println("中介带你看房");
}
//收中介费
public void fare(){
System.out.println("收中介费");
}
//合同
public void hetong(){
System.out.println("签合同");
}
}
静态代理的例子二:
原有的实现功能:
现在有需求,想在每个方法中加一个日志功能,但要遵循不改变原有代码的原则。
新增一个proxy代理类,
最后在测试类中有如下改变:
深入理解图片:
动态代理
- 动态代理和静态代理角色一样
- 动态代理的代理类是动态生成的,不是我们直接写好的!
- 动态代理分为两大类:
- 基于接口的动态代理:JDK动态代理
- 基于类的动态代理:cglib
- 现在用的比较多的是 javasist 来生成动态代理 . 百度一下javasist
代码模板:
ProxyInvocationHandler.java
//等会我们会用这个类,自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Object target;
public void setTarget(Object target) {
this.target = target;
}
public ProxyInvocationHandler(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 result;
}
//日志
public void log(String msg){
System.out.println("执行了"+msg+"方法");
}
}
Client.java
public class Client {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
//代理角色:不存在
ProxyInvocationHandler pih = new ProxyInvocationHandler(userService);
pih.setTarget(userService);//设置要代理的对象
//动态生成代理类
UserService proxy= (UserService) pih.getProxy();
proxy.add();
}
}