mybatis进击一:动态代理实战

一、动态代理用来干什么

1、动态代理可以实现对接口的装饰,可以在一个方法执行之前和之后选择不同的操作(对于特别多方法的接口而言,会很方便)

2、各种框架里都使用动态代理,那么我们也没有理由不去学习和应用它

二、原理

java中的动态代理主要是两个类:Proxy和InvocationHandler

Proxy: 生成代理对象

InvocationHandler: 拦截对象,进行方法的校验或者增强

创建Proxy有两种方法

//这是Proxy的静态方法,用来生成代理类,代理类实现了interfaces定义的接口,类名以$Proxy开头,所以源码特别注明"请原则上不用以这个字符串命名类,尽管没有强制性的要求"
getProxyClass(ClassLoader loader,Class<?>... interfaces)
//拿到Proxy类之后,我们可以获取它的构造构造方法并进行实例化
getConstructor(InvocationHandler.class);
//获取动态代理对象,之后我们就可以随意调用方法了
newInstance(Object ... initargs)
//直接一步到位,创建代理对象
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

在这里我们可以看到都有使用InvocationHandler,这个类就是执行代理对象代理的方法

三、使用

1、勤快式

所为勤快式,就是我们可以先创建出Constructor对象,然后new Proxy时,再进行newInstance

public class MyInvocationHandler implements InvocationHandler {
    private final MergeFun mergeFun;

    public MyInvocationHandler(MergeFun mergeFun){
        this.mergeFun = mergeFun;
    }

    private final static Constructor CONSTRUCTOR;

    static {
        try {
            CONSTRUCTOR = Proxy.getProxyClass(MyInvocationHandler.class.getClassLoader(), new Class[]{Function1.class, Function2.class})
                    .getConstructor(InvocationHandler.class);
        } catch (NoSuchMethodException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /**
     * 定义成static
     * @param mergeFun
     * @return
     */
    public static Function1 newProxy(final MergeFun mergeFun){
        try {
            return (Function1) CONSTRUCTOR.newInstance(new MyInvocationHandler(mergeFun));
        } catch (InstantiationException e) {
            throw new IllegalArgumentException(e);
        } catch (IllegalAccessException e) {
            throw new IllegalArgumentException(e);
        } catch (InvocationTargetException e) {
            throw new IllegalArgumentException(e);
        }
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("invoke start");
        Object object = method.invoke(mergeFun, args);
        System.out.println("invoke result:" + object);
        return object;
    }

}

2、懒惰式

使用时再进行new instance

public class MyLazyProxy implements InvocationHandler {
    private MergeFun mergeFun;
    public MyLazyProxy(MergeFun my){
        this.mergeFun = my;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("invoke start");
        Object object = method.invoke(mergeFun, args);
        System.out.println("invoke result:" + object);
        return object;
    }

    public static Function1 newProxy(final MergeFun mergeFun){
        return (Function1) Proxy.newProxyInstance(MyLazyProxy.class.getClassLoader(),
                new Class[]{Function1.class}, new MyLazyProxy(mergeFun));
    }
}

注:MergeFun 就是要被代理的真实对象

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值