java设计模式系列四之代理模式

参考博文:
https://blog.csdn.net/gdutxiaoxu/article/details/81394050
一,概述
代理的设计理念是限制对象的直接访问,即不能通过new直接访问对象,必须通过代理类
二,UML类图
在这里插入图片描述
Subject(抽象角色):声明真实对象和代理对象的共同接口;
ProxySubject(代理角色):代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
(RealSubject)真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。调用 RealSubject 的方法,都要经过 ProxySubject 进行代理。
三,静态代理
一般来说,主要有以下几个步骤

抽象一个接口 ISubject
实现该接口 RealSubject
创建代理对象类 ProxySubject
客户端发起调用
抽象一个接口 ISubject
public interface ISubject {

void doAction(String action);

}

实现该接口 RealSubject
public class RealSubject implements ISubject {

public void doAction(String action) {
    // TODO Auto-generated method stub
    System.out.println("I am RealSubject, do action "+ action);
}

}

创建代理对象类 ProxySubject
public class ProxySubject implements ISubject {

ISubject mRealSubject;

public ProxySubject(ISubject mRealSubject) {
    super();
    this.mRealSubject = mRealSubject;
}



public void doAction(String action) {
    // TODO Auto-generated method stub
    preRequest();
    mRealSubject.doAction(action);
    postRequest();
}



protected void postRequest() {
    // TODO Auto-generated method stub
    System.out.println("postRequest");

}

protected void preRequest() {
    // TODO Auto-generated method stub
    System.out.println("preRequest");

}

}

客户端发起调用
private static void testStatical() {
RealSubject realSubject = new RealSubject();
ProxySubject proxySubject = new ProxySubject(realSubject);
proxySubject.doAction(“play”);

}

将会看到以下 log

preRequest
I am RealSubject, do action play
postRequest

四,动态代理
实现 InvocationHandler 接口,创建自己的调用处理器;
通过 Proxy.newProxyInstance 生成动态代理类实例

public class DynamicProxy implements InvocationHandler {

    private Object target;

    public DynamicProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(target,args);
    }
}


public class ClientTest {
    public static void main(String[] args) {
        Subject proxy = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(),new Class<?>[]{Subject.class},new DynamicProxy(new RealObject()));
        proxy.doSomething();
    }
}

五,CGLIB代理
这种代理不要求被代理对象必须实现某个接口

使用cglib[Code Generation Library]实现动态代理,并不要求委托类必须实现接口,底层采用asm字节码生成框架生成代理类的字节码,下面通过一个例子看看使用CGLib如何实现动态代理。
1、定义业务逻辑

public class UserServiceImpl {
public void add() {
System.out.println(“This is add service”);
}
public void delete(int id) {
System.out.println("This is delete service:delete " + id );
}
}
2、实现MethodInterceptor接口,定义方法的拦截器

public class MyMethodInterceptor implements MethodInterceptor {
public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable {
System.out.println(“Before:” + method);
Object object = proxy.invokeSuper(obj, arg);
System.out.println(“After:” + method);
return object;
}
}
3、利用Enhancer类生成代理类;

Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserServiceImpl.class);
enhancer.setCallback(new MyMethodInterceptor());
UserServiceImpl userService = (UserServiceImpl)enhancer.create();
4、userService.add()的执行结果:

Before: add
This is add service
After: add
代理对象的生成过程由Enhancer类实现,大概步骤如下:
1、生成代理类Class的二进制字节码;
2、通过Class.forName加载二进制字节码,生成Class对象;
3、通过反射机制获取实例构造,并初始化代理类对象。

六,代理模式与装饰器模式比较
装饰模式:以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案;
代理模式:给一个对象提供一个代理对象,并有代理对象来控制对原有对象的引用;

装饰模式应该为所装饰的对象增强功能;代理模式对代理的对象施加控制,并不提供对象本身的增强功能

二者的实现机制确实是一样的,可以看到他们的实例代码重复是很多的。但就语义上说,这两者的功能是相反的,模式的一个重要作用是简化其他程序员对你程序的理解,

你在一个地方写装饰,大家就知道这是在增加功能,你写代理,大家就知道是在限制,

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值