Spring学习笔记——05代理模式

一. 代理模式

代理模式作为23种经典设计模式之一,其比较官方的定义为“为其他对象提供一种代理以控制对这个对象的访问”,简单点说就是,之前A类自己做一件事,在使用代理之后,A类不直接去做,而是由A类的代理类B来去做。代理类其实是在之前类的基础上做了一层封装。java中有静态代理、JDK动态代理、CGLib动态代理的方式。静态代理指的是代理类是在编译期就存在的,相反动态代理则是在程序运行期动态生成的

二. 静态代理

1. 案例
  1. 接口

    public interface Rent {
        public void rent();
    }
    
  2. 实现类

    public class Host implements Rent {
        public void rent() {
            System.out.println("房东出租房子");
        }
    }
    
  3. 代理类

    public class Proxy {
        private Host host;
    
        public Proxy(){
    
        }
    
        public Proxy(Host host) {
            this.host = host;
        }
    
        public void rent(){
        	System.out.println("代理操作,开启事务");
            host.rent();
            System.out.println("代理操作,关闭事务");
        }
    }
    
  4. 测试

    public class Client {
        // 不使用代理
        @Test
        public void test01(){
            Host host = new Host();
            host.rent();
        }
    
        // 通过代理调用
        @Test
        public void test02(){
            Host host = new Host();
            // 代理
            Proxy proxy = new Proxy(host);
            proxy.rent();
        }
    }
    
2. 说明:
  1. 对比,使用静态代理和不使用静态代理,可以发现使用了代理之后,可以在被代理方法的执行前或后加入别的代码,实现诸如权限及日志的操作。
  2. 静态代理也存在一定的问题,如果被代理方法很多,就要为每个方法进行代理,增加了代码维护的成本。有没有其他的方式可以减少代码的维护,那就是动态代理。

三. JDK动态代理

1. 案例
  1. 接口

    public interface Rent {
        public void rent();
    }
    
  2. 实现类

    public class Host implements Rent {
        public void rent() {
            System.out.println("房东出租房子");
        }
    }
    
  3. 动态代理类

    // 动态生成代理类
    public class ProxyInvocationHandler implements InvocationHandler {
        // 被代理的接口
        private Rent rent;
    
        public void setRent(Rent rent) {
            this.rent = rent;
        }
    
        // 生成得到代理类
        public Object getProxy(){
            return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                    rent.getClass().getInterfaces(), this);
        }
    
        // 处理代理实例, 并返回代理结果
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 动态代理的本质: 就是使用反射机制实现
            seeHouse();
            Object result = method.invoke(rent, args);
            fare();
            return result;
        }
        
        public void seeHouse() {
            System.out.println("中介带着看房");
        }
    
        public void fare(){
            System.out.println("中介收取中介费");
        }
    }
    
    
  4. 测试

    public class Client {
        @Test
        public void test01(){
            // 真实角色
            Host host = new Host();
            // 代理角色, 现在没有
            ProxyInvocationHandler handler = new ProxyInvocationHandler();
            // 通过调用程序处理角色来处理我们要调用的接口对象
            handler.setRent(host);
            Rent proxy = (Rent) handler.getProxy();
            proxy.rent();
        }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值