JDK动态代理[1]----代理模式实现方式的概要介绍

日常工作中经常会接触到代理模式,但一直没有对其进行深究。代理模式一直就像一团迷雾一样存在我心里,什么是代理模式?为什么要使用代理?代理模式有哪些实现?它的底层机制是怎样的?这些问题促使着我迫切想要揭开代理模式的神秘面纱。

1. 什么是代理模式?

日常生活中我们经常会碰到代理模式,例如我们找房产中介帮我们介绍房子,找婚姻中介帮我们介绍对象,找保洁帮我们打理房间,找律师帮我们进行诉讼等。我们在无形中运用到了代理模式,却不知道它的存在。

2. 为什么要使用代理?

运用代理可以使我们的生活更加便利,有了代理,我们不需要自己去找房子,不需要自己去找对象,不需要自己去打理房间,不需要自己去诉讼。当然,你也可以选择一切都自己来干,但是存在前提条件,一是你是否都具备这样的资源和能力来做这些事情,二是你是否愿意花费这么多精力和时间来做这些事情。总之,代理模式使我们各专其事,我们可以将时间浪费在美好的事情上,而不用天天被一些琐事所羁绊。

3. 代理模式有哪些实现?

Java中的代理有静态代理和动态代理,下面我会分别用一个简单的例子来介绍一下静态代理和动态代理代码实现。

3.1 静态代理

代理接口:UserDao.java

public interface UserDAO {
    void save();
}

目标对象:UserDaoImpl.java

    public class UserDAOImpl implements UserDAO {
        @Override
        public void save() {
            System.out.println("正在保存用户...");
        }
    }

代理对象:TransactionHandler.java

public class TransactionHandler implements UserDAO {
    private final UserDAO target;

    public TransactionHandler(UserDAO target) {
        this.target = target;
    }

    @Override
    public void save() {
        // 调用目标方法前的处理
        System.out.println("开启事务控制...");
        // 调用目标对象的方法
        this.target.save();
        // 调用目标方法后的处理
        System.out.println("关闭事务控制...");
    }
}

测试结果:
测试结果

3.2 动态代理

代理接口:UserDao.java

public interface UserDAO {
    void save();
}

目标对象:UserDaoImpl.java

    public class UserDAOImpl implements UserDAO {
        @Override
        public void save() {
            System.out.println("正在保存用户...");
        }
    }

代理对象:TransactionHandler.java

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class TransactionHandler implements InvocationHandler {
    private final Object target;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 调用目标方法前的处理
        System.out.println("开启事务控制...");
        // 调用目标对象的方法
        Object result = method.invoke(this.target, args);
        // 调用目标方法后的处理
        System.out.println("关闭事务控制...");
        // 返回方法调用结果
        return result;
    }
}

测试类:Main.java

import java.lang.reflect.Proxy;

public class Main {
    public static void main(String[] args) {
        // 新建目标对象
        Object target = new UserDAOImpl();

        // 创建事务处理器
        TransactionHandler handler = new TransactionHandler(target);

        // 生成代理类,并使用接口对其进行引用
        UserDAO userDAO = (UserDAO) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);

        // 针对接口进行方法调用
        userDAO.save();
    }
}

测试结果:
测试结果

总结:

之前我们发现了静态代理会产生许多重复代码,不能很好的进行代码复用,而动态代理能够很好的解决这个问题,代理类TransactionHandler实现了InvocationHandler接口,并且它持有的目标对象类型是Object,因此事务控制代理类TransactionHandler能够代理任意的对象,为任意的对象添加事务控制的逻辑。因此动态代理才真正的将代码中横向切面的逻辑剥离了出来,起到代码复用的目的。但是动态代理也有缺点,一是它的实现比静态代理更加复杂也不好理解;二是它存在一定的限制,例如它要求需要代理的对象必须实现了某个接口;三是它不够灵活,动态代理会为接口中的声明的所有方法添加上相同的代理逻辑。当然,这只是JDK动态代理所存在的一些缺陷,动态代理还有另外的实现如使用CGLIB库,在本文不做介绍,读者可以自行去了解。

全文总结:

本文从概念上为大家介绍了什么是代理模式,为什么要使用代理以及代理模式有哪些实现,并使用简单的例子为大家介绍静态代理和JDK动态代理的实现,分析了静态代理和动态代理各自的优缺点,使大家对代理模式有了一些大致的了解。不过到这里相信读者对于JDK动态代理还是会感到困惑,想要进一步了解代理类是怎样产生的。后续章节笔者会深入源码为大家呈现整个代理类的产生过程。

原文链接:https://www.cnblogs.com/liuyun1995/p/8144628.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值