动态代理JDK/CGLib

动态代理

JDK 动态代理

创建接口及具体实现类

public interface BingoOk {

    /**
     *
     * @param who
     * @return
     */
    public String lookLook(String who);


    /**
     *
     * @return
     */
    public String ohMyGod();

}

public class BingoOkImpl implements BingoOk{
    @Override
    public String lookLook(String who) {
        System.out.println("推开门了");
        return "让"+who+"来看看~~";
    }

    @Override
    public String ohMyGod() {
        System.out.println("赶紧跑");
        return "oh my god,看到了啥!!!";
    }
}

实现InvocationHandler 接口的invoke方法

public class JDKProxyLearn implements InvocationHandler {

    private Object object;

    /**
     * 指定需要代理的对象
     * @param object
     */
    public JDKProxyLearn(Object object){
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("invoke 来了。偷窥开始~");

        System.out.println("method : "+method);

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

        System.out.println("invoke 完了。偷窥完了~");
        return invoke;
    }
}

具体方法及实现

public class TestJDKProxy {


    public static void main(String[] args) {
        BingoOk ok = new BingoOkImpl();

        // 实现 InvocationHandler 接口,传入ok接口 代理 这个ok。具体嵌入方法
        InvocationHandler handler = new JDKProxyLearn(ok);

        //获取 需要代理的 ok 接口的 classloader
        ClassLoader classLoader = ok.getClass().getClassLoader();

        //获取 需要代理的 ok 接口的 interfaces
        Class<?>[] interfaces = ok.getClass().getInterfaces();

        // 指定代理的 classloader ,interfaces 还有 执行
        BingoOk o = (BingoOk)Proxy.newProxyInstance(classLoader, interfaces, handler);

        System.out.println("代理了呀 : " +o.getClass().getName());

        String value = o.lookLook("海少");
        System.out.println(value);
//        String s = o.ohMyGod();
//        System.out.println(s);
    }
}

关键方法是 Proxy.newProxyInstance ,对应生成的最终的class可以发现,对象 继承了 Proxy类 实现了 自定义的接口。 因为Java 单继承多实现,所以 JDK动态代理对象不支持对实现类的代理,只支持接口的代理。

CGLIB 动态代理

直接新建需要代理的类

public class BingoOk {

    public String lookLook(String who) {
        System.out.println("推开门了");
        return "让"+who+"来看看~~";
    }

    public String ohMyGod() {
        System.out.println("赶紧跑");
        return "oh my god,看到了啥!!!";
    }
}

实现MethodInterceptor的intercept方法

public class CGLibProxyLearn implements MethodInterceptor {

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("invoke 来了。偷窥开始~");

        System.out.println("method : "+method);

        Object invoke = methodProxy.invokeSuper(o,objects);

        System.out.println("invoke 完了。偷窥完了~");
        return invoke;
    }
}

具体方法及实现

public class TestCGLibProxy {

    public static void main(String[] args) {
        BingoOk ok = new BingoOk();

        Enhancer enhancer = new Enhancer();

        enhancer.setSuperclass(ok.getClass());
        enhancer.setCallback(new CGLibProxyLearn());


        BingoOk instance = (BingoOk)enhancer.create();

        System.out.println("代理开始了" + instance.getClass().getName());

        String value = instance.lookLook("海少2");

        System.out.println(value);


    }
}

关键注意Enhancer 增强类,设置增强类的类型,和代理方法。创建代理对象并通过代理对象执行。对应生成的最终的class可以发现,代理对象继承了 实现类,实现了 Factory 接口。所以相当于通过子类来实现的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值