代理模式

一、代理模式的概念

代理(Proxy)模式:为其他对象提供一个代理以控制对某个对象的访问,即通过代理对象访问目标对象

 

二、代理模式的实现

1、静态代理

在程序运行前就已经存在代理类的字节码文件

代理类和委托类的关系在运行前确定

//统一接口
public interface Subject{
    
    public void doAction();
}
//委托类
public class RealSubject implements Subject{

    public void doAction(){
        
        //TODO
    }
}
//代理类
public class MyProxy implements Subject{
    
    //目标对象
    private Subject realSubject;

    public MyProxy(Subject realSubject){

        this.realSubject = realSubject;
    }

    public void doAction(){

        //before TODO

        realSubject.doAction();

        //after TODO
    }
}

pros and cons :

在目标方法调用前后增加处理过程(日志、权限等)

代理类和委托类实现了相同的接口,出现了大量重复代码(如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法)

每个代理对象只服务于一种类型的对象(代理对象需要实现与委托对象相同的接口)

2、动态代理

在程序运行期间由JVM根据反射等机制动态生成代理类的源码

代理类和委托类的关系是在运行时确定

2.1 JDK动态代理

java.lang.reflect包提供Proxy类和InvocationHandler接口

//接口
public interface Subject{
    
    public void doAction();
}
//委托类
public class RealSubject implements Subject{

    public void doAction(){
        
        //TODO
    }
}
//调用处理器
public class Handler implements InvocationHandler {

    //目标对象
    private Subject realSubject;

    public Handler(Subject realSubject){

        this.realSubject = realSubject;
    }

    /**
     * proxy——代理对象
     * method——目标方法
     * args——目标方法实参
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
        //before TODO

        Object object = method.invoke(realSubject, args);

        //after TODO

        return object;
    }
}
public class Test {
    public static void main(String[] args) {
        
        //委托对象
        Subject realSubject = new RealSubject();
        
        //调用处理器(与委托对象关联)
        InvocationHandler handler = new Handler(realSubject);
        
        //代理对象(代理对象方法的调用触发Handler中invoke方法的执行)
        Subject subjectProxy = (Subject)Proxy.newProxyInstance(
                   Subject.class.getClassLoader(),new Class<?>[]{Subject.class}, handler);

        subjectProxy.doAction();
    }
}

深入剖析 \ ( > < ) /……

pros and cons :

对代理类的函数进行统一的处理,不用修改每个代理类中的方法(所有被代理执行的方法通过InvocationHandler中的invoke方法调用的,只要在invoke方法中统一处理,就可以对所有被代理的方法进行相同的操作)

只能对接口实现代理(动态生成的代理对象实际继承【extends】Proxy类实现【implements】目标接口)

2.2 CGLIB动态代理

cglib是针对类(接口也行)来实现代理,对指定的类生成一个子类,并覆盖其中方法实现代理

因为采用的是继承,所以不能对final修饰的类进行代理 

//接口
public interface Subject{
    
    public void doAction();
}
public class Interceptor implements MethodInterceptor {  

    //实现回调方法 
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)         
                                                                       throws Throwable { 
        
        //before TODO

        //调用业务类(父类中)的方法
        proxy.invokeSuper(obj, args); 

        //after TODO

        return null; 
    }
public class Test{

    Subject realSubject = new RealSubject();
    //拦截器
    MethodInterceptor intercepter = new Intercepter();
    //增强器
    Enhancer enhancer = new Enhancer();
    //给代理类指定父类
    enhancer.setSuperClass(realSubject.getClass());
    //设置回调(代理类上所有方法的调用都会调用Callback,Callback需要实现intercept()方法进行拦截)
    enhancer.setCallback(intercepter);
    //创建代理对象
    Subject subjectProxy = (Subject)enhancer.create();

    subjectProxy.doAction();
}

深入剖析 \ ( > < ) /……

 

三、代理模式的应用

Spring AOP 的实现

可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能
不要随意去修改别人写好的代码或者方法,需要时可以通过代理的方式来扩展

 

四、代理模式の其他问题

静态代理是在代码中显式定义一个代理类,通过代理类同名的方法调用被包装过的业务方法

JDK动态代理是通过接口中的方法名,在动态生成的代理类中调用业务实现类的同名方法

CGLIB动态代理是通过继承业务类,生成的动态代理类是业务类的子类,通过重写业务方法进行代理

 

五、Reference

       动态代理实现与原理分析

       动态代理之JDK实现和CGlib实现

       静态代理与动态代理的区别

 

 

六、Resource


       大话设计模式

       Head First 设计模式

       Java设计模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值