代理模式三种实现案例

阅读本文需要一定面向对象以及类反射机制基础 反射机制详解

代理模式的主要作用:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式的思想:为了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象进行通信。
因此我们可以通过代理模式来实现对某个对象方法的重写及维护

静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类.本案例通过实现接口来实现静态代理

1. 静态代理实现

public interface Run {
    void run();
}
public class RealizeRun implements Run {

    @Override
    public void run() {
        System.out.println("RealizeRun.run()");
    }

}
public class StaticProxy implements Run{
    private Run myrun;
    public StaticProxy(Run myrun) {
        this.myrun = myrun;
    }
    @Override
    public void run() {
        // 重构或添加run方法的执行
        System.out.println("StaticProxy.run() begin");
        myrun.run();
        System.out.println("StaticProxy.run() end");
    }

}
public class TheadMain {
    public static void main(String[] args) {
        RealizeRun run = new RealizeRun();
        StaticProxy myrun = new StaticProxy(run);
        myrun.run();
    }
}

静态代理实现实例:
(代理类)HttpServletRequestWrapper (接口)HttpServletRequest

2. 动态代理

动态代理有两种实现方式:jdk自带的 java.lang.reflect.Proxy 和 第三方工具Cglib实现动态代理
Proxy 代理模式:代理对象不需要实现接口,但是目标对象一定要实现接口,否则不能用动态代理,底层通过反射机制实现对象的接口实现
Cglib 代理模式:代理对象不需要实现接口,、目标对象通过继承该类实现重构该类的方法
Proxy和Cglib区别


import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
/**
 * Proxy 代理
 * @author xiaoqiang
 * 通过集合类案例实现接口代理
 */
public class MyProxy {

    public static void main(String[] args){
        List<String> arr = new ArrayList<String>();
        /*
         * 我要重写add方法 让他直接输出在控制台 ClassLoader loader 你所需要代理对象的类加载器 Class<?>[]
         * interfaces 所有你需要代理的方法的接口.class 对象 InvocationHandler h 处理接收接口中的方法
         */

        /*
         * 注意第二个参数为所有需要处理方法的接口 因为add方法在List接口中所以我就直接获取了List接口 也可以写
         * rr.getClass().getInterfaces() 该方法返回ArrayList 实现的所有接口
         */

        @SuppressWarnings("unchecked")
        List<String> list =  (List<String>) Proxy.newProxyInstance(arr.getClass().getClassLoader(), arr.getClass().getInterfaces(),
                (proxy, method, a) -> {
                    // 方法返回值
                    Object result = null;
                    // 当前执行的方法的方法名
                    String methodName = method.getName();
                    // 判断当执行了add方法的时候
                    if ("add".equals(methodName)) {
                    System.out.println(a[0]);
                    }
                    // 调用目标对象原来的方法
                    result = method.invoke(arr, a);
                    return result;
                });
        list.add("xiaoqiang");
    }

}

Cglib依赖包以及下载


import java.lang.reflect.Method;
import java.util.ArrayList;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * Cglib代理
 * @author xiaoqiang
 * Cglib子类代理工厂
 * 对传入对象的方法进行追踪重构
 */
public class CglibProxy implements MethodInterceptor {
    private Object target;

    public CglibProxy(Object target) {
        this.target = target;
    }
    //给目标对象创建一个代理对象
    public Object getProxyInstance(){
        //1.工具类
        Enhancer en = new Enhancer();
        //2.设置父类
        en.setSuperclass(target.getClass());
        //3.设置回调调用intercept方法
        en.setCallback(this);
        //4.创建子类(代理对象)
        return en.create();

    }
    /**
     * 拦截所有目标类方法的调用
     * obj  目标类的实例
     * m   目标方法的反射对象
     * args  方法的参数
     * proxy代理类的实例
     */
    @Override
    public Object intercept(Object obj, Method m, Object[] args,
            MethodProxy proxy) throws Throwable {
        // 若方法名为add
        if("add".equals(m.getName())){
            // 输出方法的第一个参数
            System.out.println(args[0]);
        }
        // 调用原来执行的方法
        return proxy.invokeSuper(obj, args);
    }
    public static void main(String[] args) {
        ArrayList<String> arr = new ArrayList<String>();
        ArrayList<String> proxyarr = (ArrayList<String>) new CglibProxy(arr).getProxyInstance();
        proxyarr.add("xiaoqiang");
    }
}
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值