CGlib 入门

CGlib 入门CGlib入门cglibgithub地址链接。项目maven构建:cglibcglib3.1项目gradle构建:dependencies{compile’cglib:cgl

大家好,又见面了,我是你们的朋友全栈君。

CGlib 入门

cglib github地址链接

项目maven构建:

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.1</version>
</dependency>

项目gradle构建:

dependencies { compile 'cglib:cglib:3.1' testCompile 'junit:junit:4.11' }

cglib不仅可以动态创建实现了接口类的代理对象,还可以为简单的POJO动态创建代理对象;而java只能动态创建实现了接口类的代理对象(使用Proxy类和InvocationHandler接口)。

1,Enhancer和FixedValue

cglib中最重要的就是net.sf.cglib.proxy.Enhancer这个类,与java中的Proxy类有异曲同工之妙,都可以创建代理对象。

下面就来简单实验一下:
首先新建一个简单的POJO类CGlibSample.java

public class CGlibSample { 
   

    public String test(String input){
        return input;
    }
}

测试类TestCG.java:

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.FixedValue;
import org.junit.Assert;
import org.junit.Test;

public class TestCG { 
   

    @Test
    public void testFixedValue() throws Exception {

        Enhancer enhancer = new Enhancer();

        enhancer.setSuperclass(CGlibSample.class);

        /*enhancer.setCallback(new FixedValue() { @Override public Object loadObject() throws Exception { return "Hello cglib!"; } });*/

        //java lambda expression 与上面的代码段效果一样
        enhancer.setCallback((FixedValue)() -> {
            return "Hello cglib!";
        });

        CGlibSample proxy = (CGlibSample)enhancer.create();

        Assert.assertEquals("Hello cglib!",proxy.test("hello!"));
        Assert.assertEquals("Hello cglib!",proxy.toString());
        Assert.assertFalse("hello!".equals
        (proxy.test("hello!")));    

    }
}

这里的FixedValue接口相当于一个拦截器(interceptor)。
proxy.getClass()
输出结果为 class glib.CGlibSample$$EnhancerByCGLIB$$c9fa3aa1,明显可以看这是个有cglib产生的代理对象,目标对象为glib.CGlibSample
由以上代码可得cglib可以改变方法。
注意: 创建代理对象的目标对象(这里是CGlibSample)一定要有无参构造方法

2,InvocationHandler

这里的InvocationHandler接口并不是java反射包中的InvocationHandler,而是cglib中接口net.sf.cglib.proxy.InvocationHandler,其实里面的内容和java差不多,如下所示:


 public interface InvocationHandler extends Callback { 
   
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;

}
    @Test
    public void testInvocationHandler(){

        Enhancer enhancer = new Enhancer();

        enhancer.setSuperclass(CGlibSample.class);

        enhancer.setCallback(new InvocationHandler() {
            @Override
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                /** * method.getDeclaringClass() != Object.class 表示该方法不能是Object类中定义的方法,如:toString()。 * method.getReturnType() == String.class 表示方法的返回类型只能为String类型 */
                if (method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {
                    return "Hello cglib!";
                } else {
                    return "do not know what to do";
                }
            }
        });

        CGlibSample proxy = (CGlibSample) enhancer.create();

        Assert.assertTrue("Hello cglib!".equals(proxy.test("hello!")));

        Assert.assertTrue("do not know what to do".equals(proxy.toString()));

    }

3,MethodInterceptor

    @Test
    public void testMethodInterceptor(){

        Enhancer enhancer = new Enhancer();

        enhancer.setSuperclass(CGlibSample.class);
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                if (method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {
                    return "Hello cglib!";
                } else {
                    //这里有点像struts2中拦截器链
                    return proxy.invokeSuper(obj,args);
                }
            }
        });

        CGlibSample proxy = (CGlibSample) enhancer.create();

        Assert.assertTrue("Hello cglib!".equals(proxy.test("hello!")));

        Assert.assertFalse("do not know what to do".equals(proxy.toString()));
    }

4,CallbackFilter

接口CallbackFilter实现类CallbackHelper。

    @Test
    public void testCallbackFilter(){

        Enhancer enhancer = new Enhancer();

        CallbackHelper callbackHelper = new CallbackHelper(CGlibSample.class,new Class[0]) {
            @Override
            protected Object getCallback(Method method) {
                if (method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {
                    return new FixedValue() {
                        @Override
                        public Object loadObject() throws Exception {
                            return "Hello cglib!";
                        }
                    };
                } else {
                    return NoOp.INSTANCE;
                }
            }
        };

        enhancer.setSuperclass(CGlibSample.class);
        enhancer.setCallbackFilter(callbackHelper);
        enhancer.setCallbacks(callbackHelper.getCallbacks());

        CGlibSample proxy = (CGlibSample) enhancer.create();

        Assert.assertTrue("Hello cglib!".equals(proxy.test("hello!")));
        System.out.println(proxy.hashCode());
        Assert.assertFalse("do not know what to do".equals(proxy.toString()));

注意:不要使用非静态的匿名内部类,会造成内存泄露。本文使用非静态的匿名内部类是为了方便。

5,Immutable Bean

    @Test(expected = java.lang.IllegalStateException.class)
    public void testImmutableBean(){

        SampleBean sampleBean = new SampleBean();

        sampleBean.setValue("Hello cglib");

        SampleBean immutableBean = (SampleBean) ImmutableBean.create(sampleBean);

        Assert.assertTrue("Hello cglib".equals(immutableBean.getValue()));

        sampleBean.setValue("Hello cglib again");
        Assert.assertTrue("Hello cglib again".equals(immutableBean.getValue()));

        immutableBean.setValue("Hello World!");//throw Exception java.lang.IllegalStateException: Bean is immutable
    }

6,Bean Generator

    @Test
    public void testBeanGenerator() throws Exception{

        BeanGenerator beanGenerator = new BeanGenerator();

        beanGenerator.addProperty("value",String.class);

        Object bean = beanGenerator.create();
        //获取bean的setter方法
        Method setter = bean.getClass().getMethod("setValue",String.class);
        setter.invoke(bean,"Hello cglib");

        //获取bean的getter方法
        Method getter = bean.getClass().getMethod("getValue");

        Assert.assertTrue("Hello cglib".equals(getter.invoke(bean)));


    }

7,Bean Copier

OtherSampleBean:

public class OtherSampleBean { 
   

    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

测试案例:

    @Test
    public void testBeanCopier(){

        BeanCopier copier = BeanCopier.create(SampleBean.class,OtherSampleBean.class,false);

        SampleBean sampleBean = new SampleBean();
        sampleBean.setValue("sample bean");

        OtherSampleBean otherSampleBean = new OtherSampleBean();
        copier.copy(sampleBean,otherSampleBean,null);

        Assert.assertTrue("sample bean".equals(otherSampleBean.getValue()));
    }

8,Bulk Bean

    @Test
    public void testBulkBean(){

        BulkBean bulkBean = BulkBean.create(SampleBean.class,
                new String[]{
  
  "getValue"},
                new String[]{
  
  "setValue"},
                new Class[]{String.class});

        SampleBean bean = new SampleBean();
        bean.setValue("sample bean");

        Assert.assertTrue(bulkBean.getPropertyValues(bean).length == 1);

        Assert.assertTrue("sample bean".equals(bulkBean.getPropertyValues(bean)[0]));

        bulkBean.setPropertyValues(bean,new Object[]{
  
  "bulk bean"});

        Assert.assertTrue("bulk bean".equals(bean.getValue()));
    }

9,Bean Map

    @Test
    public void testBeanMap(){

        SampleBean bean = new SampleBean();

        BeanMap map = BeanMap.create(bean);
        bean.setValue("bean mao");

        Assert.assertTrue("bean mao".equals(map.get("value")));

    }
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/135174.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 什么是计算机补码_二进制原码反码补码

    什么是计算机补码_二进制原码反码补码计算机中数字都是用二进制来表示的,有三种编码方式:原码、反码、补码,而计算中用到最多的就是补码,原因是什么呢?让我们来看一下这三种方式的具体表示吧原码原码的表达很简单,最高位为符号位,0表示正数,1表示负数。其它位即为绝对值的二进制表示,非常直观。但是使用原码存在哪些问题呢?0的表示存在二义性如果按照上述的表示方式,那么0就可以分为+0和-0两种表示。即以8位字长来说+0的原码为00000000…

    2022年10月21日
    3
  • 这个问题让我疯掉!用oledbcommand执行一个插入一条记录的程序,到现在也没有解决!…

    这个问题让我疯掉!用oledbcommand执行一个插入一条记录的程序,到现在也没有解决!…数据库结构:StringStr=”INSERTINTODataHis(时间,开盘价,最高价,最低价,收盘价)VALUES(’98-02-12′,4,34,45,56)”;//StringStr=”select*fromDataHis”;stringstrConn=”Provider=Mic…

    2022年5月12日
    29
  • 用python实现关机程序_python实现重启关机程序

    用python实现关机程序_python实现重启关机程序python实现重启关机程序发布于2014-08-2523:12:16|595次阅读|评论:0|来源:网友投递Python编程语言Python是一种面向对象、解释型计算机程序设计语言,由GuidovanRossum于1989年底发明,第一个公开发行版发行于1991年。Python语法简洁而清晰,具有丰富和强大的类库。它常被昵称为胶水语言,它能够把用其他语言制作的各种模块…

    2022年7月22日
    14
  • 【2022最新Java面试宝典】—— Java基础知识面试题(91道含答案)

    【2022最新Java面试宝典】—— Java基础知识面试题(91道含答案)目录一、Java概述1.何为编程2.什么是Java3.jdk1.5之后的三大版本4.Jdk和Jre和JVM的区别5.什么是跨平台性?原理是什么6.Java语言有哪些特点7.什么是字节码?采用字节码的最大好处是什么8.什么是Java程序的主类?应用程序和小程序的主类有何不同?9.Java应用程序与小程序之间有那些差别?10.Java和C++的区别11.OracleJDK和OpenJDK的对比二、基础语法数据类型12.Java有哪些数据类型13.switch是否能作用在by

    2022年9月20日
    3
  • iReport 设计介绍「建议收藏」

    iReport 设计介绍「建议收藏」目录iReport用户手册………………………………………………………………………………………………1iReport用户手册-介绍………………………………………………..

    2025年10月21日
    4
  • 在毕设中学习03

    在毕设中学习035.24文献阅读记录脑电分为诱发性脑电和自发性脑电,诱发性脑电的诱发因素又分为外源性刺激(视觉听觉触觉)和内源性事件相关(计算、思考)keras库keras以TensorFlow/Theano作为后端封装,是一个专门用于深度学习的python模块。包含了全连接层,卷积层,池化层,循环层,嵌入层等等等,常见的深度学习模型。包含用于定义损失函数的Losses用于训练模型的Optimizers评估模型的Metrics定义激活函数的Activations防止过拟合的Regularizers等mn

    2022年8月11日
    7

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号