栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

动态代理(cglib实现)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

动态代理(cglib实现)

目录

原理实例

cglib代码实例

注意:测试要是发生报异常


cglib是利用生成子类继承父类的方法实现的动态代理

原理实例

首先构造父类Singer

public class Singer {
    public void dance(){
        System.out.println("跳舞");
    }
    public void singing(){
        System.out.println("唱歌"); 
    }
}

构造子类继承父类,实现代理

public class SingerSub extends Singer {
    @Override
    public void dance() {
        System.out.println("经纪人商量合同");
        super.dance();
        System.out.println("收钱");

    }
    @Override
    public void singing() {
        System.out.println("经纪人商量合同");
        super.singing();
        System.out.println("收钱");
    }
}

方法执行

public class Main {
    public static void main(String[] args) {
        Singer singer = new SingerSub();
        singer.singing();
        singer.dance();
    }
}

运行结果

可以看出,我并未用静态代理,也没有用proxy类去实现,就是单纯的继承关系。理解到这就是cglib的原理

cglib代码实例

首先之前一样建立Singer接口

public interface Singer {
    void sing();
    void dance();
}

然后实现方法

public class ZStar implements Singer{
    @Override
    public void sing() {
        System.out.println("我会唱歌.......");
    }
    @Override
    public void dance() {
        System.out.println("我会跳舞......");
    }
}

建立代理规则,这一步和Proxy有很大相似性,只不过是proxy继承的InvocationHandler接口,而cglib继承的是MethodInterceptor,

public class TargetCglib implements MethodInterceptor  {
    private ZStar zStar;
    public TargetCglib(ZStar zStar) {
        this.zStar = zStar;
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("签合同");
        Object invoke = methodProxy.invokeSuper(o, objects);//调用原方法
        //Object invoke = method.invoke(zStar, objects);
        //Object invoke = methodProxy.invokeSuper(zStar, objects);
        System.out.println("收钱");
        return invoke;
    }
}

其中注释的内容是三种不同的代理执行方法的方法,可以自己试试。

要说明的是
invokeSuper调用的是被代理类的方法, 但只有代理类才存在基类, 必须使用代理类作为obj参数调用
invoke调用的是增强方法, 必须使用被代理类的对象调用, 使用代理类会造成OOM

主方法运行

public class Main {
    public static void main(String[] args) {
        Enhancer en = new Enhancer();//用来帮我们生成代理对象
        en.setSuperclass(ZStar.class);//设置要代理的目标类
        en.setCallback(new TargetCglib(new ZStar()));//设置执行规则,相当于proxy的Ruler
        ZStar s = (ZStar)en.create();//创造代理对象
        s.dance();//方法测试
        System.out.println("********************");
        s.sing();

    }
}

其中Enhancer就是cglib用来帮我们生成代理对象的,再用setSuperclass设定代理的目标类,在设定代理规则,也就是我们上边设定的签合同收钱,create()生成代理对象,测试运行得到结果

注意:测试要是发生报异常

Exception in thread "main" java.lang.NoClassDefFoundError: org/objectweb/asm/Type

.................

Caused by: java.lang.ClassNotFoundException: org.objectweb.asm.Type

可以试着换一下cglib的jar包,更换成cglib-full.jar

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/768680.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号