设计模式之代理模式

代理模式用于在访问对象时增加额外控制,如事务、日志等。Spring的AOP即依赖代理实现。文章通过代码展示了静态代理的实现,指出了其需要为每个真实对象创建代理对象的缺点,然后引入了JDK动态代理,演示了如何动态地为任何对象添加代理。
摘要由CSDN通过智能技术生成

 为其他对象提供一种代理以控制对这个对象的访问,避免直接访问对象带来的问题,比如需要事务控制,需要异步,在访问一个类时做一些控制,比如Spring的AOP就是依赖代理实现,可以不嵌入原本业务代码,动态添加功能。

直接看代码吧

真实对象:

interface Subject {

    /**
     * 对象请求
     */
    void request();

}

@Log4j2
class RealSubject implements Subject {

    @Override
    public void request() {
        log.info("真实对象请求");
    }
}

代理对象需要持有一个真实对象:

@Log4j2
@Data
class StaticProxy implements Subject {

    private Subject realSubject;

    @Override
    public void request() {
        log.info("静态代理对象请求");
        realSubject.request();
    }
}

通过代理对象访问真实对象:

        Subject subject = new RealSubject();
        log.info("没有代理");
        subject.request();
        log.info("有代理");
        StaticProxy staticProxy = new StaticProxy();
        staticProxy.setRealSubject(subject);
        staticProxy.request();

结果:

15:37:26.319 [main] INFO com.learn.putc.designpatterns.structure.proxy.ProxyPattern - 没有代理
15:37:26.327 [main] INFO com.learn.putc.designpatterns.structure.proxy.RealSubject - 真实对象请求
15:37:26.328 [main] INFO com.learn.putc.designpatterns.structure.proxy.ProxyPattern - 有代理
15:37:26.329 [main] INFO com.learn.putc.designpatterns.structure.proxy.StaticProxy - 静态代理对象请求
15:37:26.329 [main] INFO com.learn.putc.designpatterns.structure.proxy.RealSubject - 真实对象请求

在执行真实对象请求前后 我们都可以做些其它事,比如日志打印、统计耗时、加事务控制

但是这种代理,需要为每一种真实对象都建立个代理对象,也称静态代理

显然这样很麻烦,有没有一种方式可以动态的创建代理对象呢?

基于JDK的动态代理:

@Log4j2
@Data
class DynamicProxy<T> implements InvocationHandler {

    private T target;

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        log.info("动态代理 前");
        Object result = method.invoke(target, args);
        log.info("动态代理 后");
        return result;
    }
}

调用:

        log.info("动态代理实现");
        DynamicProxy<Subject> subjectDynamicProxy = new DynamicProxy<>();
        subjectDynamicProxy.setTarget(subject);
        Subject subjectDynamicProxy0 =
                (Subject)Proxy.newProxyInstance(
                        Subject.class.getClassLoader()
                        , new Class<?>[]{Subject.class}
                        , subjectDynamicProxy);
        subjectDynamicProxy0.request();

这样就可以灵活的为任何对象添加代理啦

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值