Java代理模式之静态代理

一、静态代理的定义与核心原理

静态代理是代理模式的一种实现方式,其核心思想是通过代理类与目标类实现相同的接口,在代理类中调用目标类的方法,并在方法调用前后添加额外功能(如日志、权限校验、性能监控等)。代理类与目标类的关系在编译时已确定,代理类需手动编写。
核心原理:

  1. 接口统一:代理类和目标类实现相同的接口,确保客户端通过接口调用时透明。
  2. 委托调用:代理类内部持有一个目标对象的引用,通过调用目标对象的方法实现核心逻辑。
  3. 功能增强:在调用目标方法前/后插入额外逻辑,如日志记录、事务管理等。

二、静态代理的实现步骤

以“房屋出租”为例,说明静态代理的实现流程:

  1. 定义接口:
    public interface HouseSubject {
        void rent(); // 出租房子的方法
    }
    
  2. 实现目标类(真实房东):
    public class RealHouseSubject implements HouseSubject {
        @Override
        public void rent() {
            System.out.println("我是房东,我要出租三室两厅的房子");
        }
    }
    
  3. 创建代理类(中介):
    public class HouseProxy implements HouseSubject {
        private HouseSubject realSubject; // 持有目标对象引用
        public HouseProxy(HouseSubject realSubject) {
            this.realSubject = realSubject;
        }
        @Override
        public void rent() {
            addAd();    // 前置操作:发布广告
            realSubject.rent(); // 调用目标方法
            removeAd(); // 后置操作:撤销广告
        }
        private void addAd() {
            System.out.println("广告:宝安西乡街道出租房子");
        }
        private void removeAd() {
            System.out.println("房子已出租,撤销广告");
        }
    }
    
  4. 客户端调用:
    public class Client {
        public static void main(String[] args) {
            HouseSubject proxy = new HouseProxy(new RealHouseSubject());
            proxy.rent();
        }
    }
    
    输出结果:
    广告:宝安西乡街道出租房子
    我是房东,我要出租三室两厅的房子
    房子已出租,撤销广告
    

三、静态代理的优缺点分析

优点 缺点
1. 代码结构清晰:代理与目标类职责分离,易于维护。 1. 代码冗余:每个目标类需对应一个代理类,接口变更时需修改所有代理类。
2. 功能扩展灵活:可在代理类中添加日志、权限校验等通用逻辑。 2. 维护成本高:接口新增方法时,需同步修改代理类和目标类。
3. 适用简单场景:适合接口稳定、功能扩展需求较少的场景。 3. 灵活性不足:无法动态生成代理类,扩展性受限。

四、典型应用场景

  1. 安全控制
    在方法调用前验证用户权限,例如:
    public class SecurityProxy implements UserService {
        private UserService realService;
        @Override
        public void save(User user) {
            if (checkPermission()) {
                realService.save(user);
            } else {
                throw new SecurityException("无权限操作");
            }
        }
    }
    
  2. 日志记录
    在方法执行前后记录日志:
    public class LogProxy implements Subject {
        @Override
        public void doSomething() {
            System.out.println("开始执行方法");
            realSubject.doSomething();
            System.out.println("方法执行完毕");
        }
    }
    
  3. 事务管理
    在数据库操作前后开启和提交事务:
    public class TransactionProxy implements Dao {
        @Override
        public void insert() {
            try {
                connection.setAutoCommit(false);
                realDao.insert();
                connection.commit();
            } catch (Exception e) {
                connection.rollback();
            }
        }
    }
    

五、静态代理与动态代理的对比

维度 静态代理 动态代理
生成时机 编译时生成代理类 运行时动态生成代理类
灵活性 需手动维护代理类 自动生成,无需手动编写
适用场景 接口稳定、简单场景 接口频繁变化、复杂系统
性能 高(无反射开销) 中(JDK动态代理)或高(CGLIB)

六、总结

静态代理通过手动实现代理类,为目标类提供功能增强,适用于接口稳定、需求简单的场景。其优点在于代码清晰、易于维护,但缺点是代码冗余和扩展性差。在实际开发中,若需处理复杂逻辑或动态生成代理类,可结合动态代理(如JDK或CGLIB)实现更灵活的扩展。

你可能感兴趣的:(#,Java知识点,代理模式,笔记,java,设计模式,学习)