java设计模式-结构型-代理模式

定义:

     为其他对象提供一种代理,以控制对这个对象的访问

解释:

     代理对象在客户端和目标对象之间起到中介作用

适用场景

         保护目标对象

         增强目标对象

缺点

         增加类的数目

         增加了系统的复杂度

   分类

          静态代理

          动态代理

          CGLib代理

 Spring代理选择 

  •           Bean有实现接口时使用动态代理
  •           Bean没有实现接口时使用CGlib

静态代理

示例代码

public interface SellHouse {
    void sell();
}
public class SellHouseOwner implements SellHouse {

    public void sell() {
        System.out.println("卖房子");
    }
}
public class SellHouseStaticProxy implements SellHouse {

    SellHouseOwner realHouseOwner;
    public SellHouseStaticProxy(){
        this.realHouseOwner=new SellHouseOwner();

    }
    public void sell() {
        System.out.println("发布房源");
        this.realHouseOwner.sell();
        System.out.println("房子已卖掉,撤销房源");
    }
}

这么一看,静态代理和前面的装饰者模式很像。

静态代理和装饰者的区分

共同点

  1. 都要实现与目标类相同的接口
  2. 这两个类中都要声明目标对象
  3. 不修改目标类的前提下增强目标方法

区别

  1. 装饰者目的就是增强目标对象,而静态代理是为保护和隐藏目标对象
  2. 装饰者模式中可以有很多继承于基类的子类,而代理者只有一个代理类
  3. 装饰者模式中子类的构造函数为父类对象,而代理类的构造函数的参数为被代理者

动态代理

示例代码

public interface RentHouse {
    void rent();
}
public class RentHouseOwner implements RentHouse{

    public void rent() {
        System.out.println("出租房子");
    }
}
public class HouseDynamicProxy implements InvocationHandler {
    private  Object obj;
    public HouseDynamicProxy(Object obj){
        this.obj=obj;
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(method.getName());
        System.out.println("发布房源");
        method.invoke(obj, args);
        if(method.getName().equals("rent")){
            System.out.println("房子已租掉,撤销房源");
        }else{
            System.out.println("房子已卖掉,撤销房源");
        }


        return null;
    }
}

public class Test {
    public static void main(String[] args) {
//        HouseStaticProxy houseStaticProxy=new HouseStaticProxy();
//        houseStaticProxy.sell();
        SellHouseOwner owner = new SellHouseOwner();
        InvocationHandler proxy = new HouseDynamicProxy(owner);
        SellHouse dynamicProxy = (SellHouse) Proxy.newProxyInstance(SellHouseOwner.class.getClassLoader(),
                SellHouseOwner.class.getInterfaces(), proxy);
        dynamicProxy.sell();

        RentHouseOwner owner1= new RentHouseOwner();
        InvocationHandler proxy1 = new HouseDynamicProxy(owner1);
        RentHouse dynamicProxy1 = (RentHouse) Proxy.newProxyInstance(RentHouseOwner.class.getClassLoader(),
                RentHouseOwner.class.getInterfaces(), proxy1);
        dynamicProxy1.rent();
    }
}

   输出结果

sell
发布房源
卖房子
房子已卖掉,撤销房源
rent
发布房源
出租房子
房子已租掉,撤销房源

可以发现动态代理需要实现InvocationHandler接口,method.invoke会调用被代理类里面的对应的方法,在invoke的前后,可以加上代理自己所需要的操作。而且动态代理能够动态产生不同接口类型的代理。

静态代理和动态代理的区别是在于要不要开发者自己定义 Proxy 类。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值