博客
关于我
代理模式(结构性模式)
阅读量:156 次
发布时间:2019-02-28

本文共 3618 字,大约阅读时间需要 12 分钟。

代理模式(Proxy Pattern)

代理模式(Proxy Pattern)是一种常用的设计模式,主要用于为另一个对象提供一个替代对象,以控制对原对象的访问。通过代理模式,可以在不直接暴露目标对象的情况下,间接地控制其访问或修改其状态。

代理模式的结构

代理模式的核心思想是:当目标对象的访问权限需要被控制或限制时,代理模式可以提供一个替代对象(代理对象),它可以控制对目标对象的访问。这样,客户端代码只需要与代理对象交互,而不需要直接与目标对象进行通信。

静态代理

静态代理是在运行时动态生成的代理对象,通常需要目标对象实现一个接口或继承自一个基类。这种方法的优点是实现简单,但其缺点在于,如果接口发生变化,所有相关的代理类都需要重新编译和发布。

以下是一个简单的静态代理示例:

// 接口public interface UserDao {    void save();}// 目标对象实现类public class UserDaoImpl implements UserDao {    public void save() {        System.out.println("----已经保存数据!----");    }}// 代理类public class UserDaoProxy implements UserDao {    // 维护目标对象    private UserDao target;    public UserDaoProxy(UserDao target) {        this.target = target;    }    public void save() {        System.out.println("开始事务...");        target.save(); // 调用目标对象的方法        System.out.println("提交事务...");    }}// 测试类public class TestMain {    public static void main(String[] args) {        // 目标对象        UserDao userDao = new UserDaoImpl();        // 代理对象        UserDao proxy = new UserDaoProxy(userDao);        // 调用代理对象的方法        proxy.save();    }}

静态代理的缺点

  • 接口依赖性强:因为目标对象需要实现接口,所以一旦接口发生变化,所有相关的代理类都需要重新编译和发布。
  • 类数量过多:每个接口都需要一个对应的代理类,导致类的数量急剧增加,维护成本高。

动态代理

动态代理不需要在源码中定义代理类,而是在运行时动态生成代理对象。这种方法适用于目标对象不实现任何接口的情况。

以下是一个简单的动态代理示例:

import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;// 代理工厂类public class ProxyFactory {    // 维护目标对象    private Object target;    public ProxyFactory(Object target) {        this.target = target;    }    // 获取代理对象    public Object getProxyInstance() {        return Proxy.newProxyInstance(            target.getClass().getClassLoader(),             target.getClass().getInterfaces(),             new InvocationHandler() {                @Override                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                    System.out.println("开始事务2");                    // 调用目标对象的方法                    Object returnValue = method.invoke(target, args);                    System.out.println("提交事务2");                    return returnValue;                }            }        );    }}// 测试类public class App {    public static void main(String[] args) {        // 目标对象        UserDao target = new UserDaoImpl();        // 代理对象        UserDao proxy = (UserDao) new ProxyFactory(target).getProxyInstance();        // 调用代理对象的方法        proxy.save();    }}

Cglib代理

Cglib(Code Generation Library)代理是一种基于目标对象的动态代理,它不需要目标对象实现接口,而是动态生成目标对象的子类,从而实现代理。这种方法适用于目标对象没有实现任何接口的情况。

以下是一个简单的Cglib代理示例:

import org.springframework.cglib.proxy.Enhancer;import org.springframework.cglib.proxy.MethodInterceptor;import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;// Cglib代理工厂类public class ProxyFactory implements MethodInterceptor {    // 维护目标对象    private Object target;    public ProxyFactory(Object target) {        this.target = target;    }    // 获取代理对象    public Object getProxyInstance() {        Enhancer enhancer = new Enhancer();        enhancer.setSuperclass(target.getClass());        enhancer.setCallback(this);        return enhancer.create();    }    @Override    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {        System.out.println("开始事务...");        // 调用目标对象的方法        Object returnValue = method.invoke(target, args);        System.out.println("提交事务...");        return returnValue;    }}

代理模式的总结

代理模式通过提供一个替代对象,控制对目标对象的访问,主要用于以下场景:

  • 保护目标对象:限制或限制对目标对象的访问。
  • 增加功能:在目标对象的基础上增加额外的功能。
  • 远程访问:当目标对象位于远程服务器时,通过代理对象本地访问目标对象。
  • 静态代理和动态代理是两种常见的实现方式,而Cglib代理是一种适用于特定场景的动态代理方法。在实际应用中,需要根据具体需求选择合适的代理方式。

    转载地址:http://pwrd.baihongyu.com/

    你可能感兴趣的文章
    Nginx配置好ssl,但$_SERVER[‘HTTPS‘]取不到值
    查看>>
    Nginx配置如何一键生成
    查看>>
    Nginx配置实例-负载均衡实例:平均访问多台服务器
    查看>>
    NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增删改数据分发及删除数据实时同步_通过分页解决变更记录过大问题_02----大数据之Nifi工作笔记0054
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_实现数据插入数据到目标数据库_实际操作03---大数据之Nifi工作笔记0042
    查看>>
    NIFI同步MySql数据_到SqlServer_错误_驱动程序无法通过使用安全套接字层(SSL)加密与SQL Server_Navicat连接SqlServer---大数据之Nifi工作笔记0047
    查看>>
    Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066
    查看>>
    NIFI大数据进阶_离线同步MySql数据到HDFS_02_实际操作_splitjson处理器_puthdfs处理器_querydatabasetable处理器---大数据之Nifi工作笔记0030
    查看>>
    NIFI大数据进阶_连接与关系_设置数据流负载均衡_设置背压_设置展现弯曲_介绍以及实际操作---大数据之Nifi工作笔记0027
    查看>>
    NIFI数据库同步_多表_特定表同时同步_实际操作_MySqlToMysql_可推广到其他数据库_Postgresql_Hbase_SqlServer等----大数据之Nifi工作笔记0053
    查看>>
    NIFI汉化_替换logo_二次开发_Idea编译NIFI最新源码_详细过程记录_全解析_Maven编译NIFI避坑指南001---大数据之Nifi工作笔记0068
    查看>>
    NIFI集群_内存溢出_CPU占用100%修复_GC overhead limit exceeded_NIFI: out of memory error ---大数据之Nifi工作笔记0017
    查看>>
    NIH发布包含10600张CT图像数据库 为AI算法测试铺路
    查看>>
    Nim游戏
    查看>>
    NIO ByteBuffer实现原理
    查看>>
    Nio ByteBuffer组件读写指针切换原理与常用方法
    查看>>
    NIO Selector实现原理
    查看>>
    nio 中channel和buffer的基本使用
    查看>>
    NIO基于UDP协议的网络编程
    查看>>