Java代理

代理模式

  代理模式又叫委托模式,是为某个对象提供一个代理对象,并且由代理对象控制对原对象的访问。通过代理对象对原对象的方法功能进行增强或是添加一些预处理、后处理操作。

   为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别。通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间,从而在设计上获得了更大的灵活性。

 

按照代理类的创建时间可以分为静态代理和动态代理:

  静态代理:由程序员创建代理类或特定工具自动生成源代码再对其编译。在程序运行前代理类的class文件就已经存在

  动态代理:程序运行期通过反射机制动态的生成

 

静态代理

  被代理类和代理类需要实现相同的接口或继承相同父类;

  代理类中包含一个被代理类对象;

  调用功能时代理者会调用被代理者的功能,同时附加新的操作 

  
/**
 * 共同接口
 */
public interface SellPhone {
    void sellPhone();
}

/**
 * 被代理类
 */
public class SellPhoneImpl implements SellPhone {
    @Override
    public void sellPhone() {
        System.out.println("销售手机~");
    }
}

/**
 * 代理类
 */
public class SellPhoneImplProxy implements SellPhone {

    private SellPhoneImpl sellPhone;

    public SellPhoneImplProxy(SellPhoneImpl sellPhone) {
        this.sellPhone = sellPhone;
    }

    @Override
    public void sellPhone() {
        System.out.println("售前方法~");
        sellPhone.sellPhone();
        System.out.println("售后方法~");
    }
}

/**
 * 测试
 */
public class TestProxy {
    public static void main(String[] args) {
        SellPhoneImpl sellPhone = new SellPhoneImpl();
        SellPhoneImplProxy sellPhoneImplProxy = new SellPhoneImplProxy(sellPhone);
        sellPhone.sellPhone();
        sellPhoneImplProxy.sellPhone();
    }
}
View Code

  缺点

    一个代理类只能适应一种业务,如果有新业务或者业务变动,需要实现新接口复写新的代理类或同时修改接口及实现类。

    代理类与被代理类需要实现相同方法,会产生大量冗余代码。

 

动态代理

  对代理模式而言,一般来说,被代理类与其代理类是一一对应的,这也是静态代理的特点。但是也存在这样的情况:多个代理类所做的操作相同,如统计方法调用次数、添加日志功能等等。如果是静态代理则每个代理类都含有相同的公共方法。

  在动态代理中,代理类是在运行时期生成的。因此,相比静态代理,动态代理可以很方便地对委托类的相关方法进行统一增强处理。

  JDK动态代理

    特点

      jdk动态代理是基于接口的,被代理类必须是某个接口的实现类。

      jre自带,不需要引入外部依赖。

      java.lang.reflect.Proxy

        该类用于动态生成代理类,主要的静态方法 newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)

      java.lang.reflect.InvocationHandler

        该接口只有一个invoke方法,通过该方法实现对委托类的代理的访问,是代理类完整逻辑的集中体现,包括要切入的增强逻辑和进行反射执行的真实业务逻辑都在此实现。

      

    步骤:

      1. 被代理类实现接口

      2. 新建代理类,实现 InvocationHandler 接口,在构造方法中传入一个 object 对象,实现 invoke 方法,在该方法中进行相关增强处理

      3. 调用 Proxy 类的静态方法 newProxyInstance(...),new 代理类作为 InvocationHandler 参数,new 被代理类,获取其类加载器,全部接口

      4. 调用 Proxy 类的 newProxyInstance(...) 生成的新类        

 

  CGLIB动态代理

    特点

      通过继承实现,被代理类必须能够被继承。通过被代理类创建子类,子类就是父类的代理。只能代理父类的公共方法。

 

posted @ 2020-02-10 17:57  oumae  阅读(140)  评论(0编辑  收藏  举报