CGLib用法详解

2020-02-04  本文已影响0人  睦月MTK

statement:本篇内容只是建立在我目前经验的基础之上,必然有不完善甚至是不正确的地方,请谨慎阅读,如果能指出错误与不足之处,更是不甚感激
附:本篇内容旨在基本探究一下CGLib提供了哪些功能,并提供基础示例和使用方法,本文主要内容来自于Rafael Winterhalter的文章《CGLib: The Missing Manual》,并在此基础上进行一些添加与修正。本篇内容将可能会被多次更新(如果有更深的理解,或者是需要添加的说明之处)


一、前言

1.1 CGLib介绍

CGLib是一个基于ASM字节码操纵框架之上的类生成工具,相比于底层的ASM,CGLib不需要你理解那么多必需的和字节码相关底层知识,你可以很轻松的就在运行时动态生成一个类或者一个接口。CGLib广泛应用于AOP方面和代理方面,比如Spring、Hibernate,甚至也可以用于Mock测试方面。

1.2 CGLib使用需知

CGLib有些地方需要提前引起注意,至于原因为何,我将会在最后一节说明。


二、CGLib核心用法

2.1 CGLib核心用法介绍及示例
2.2 CGLib核心用法中三大组件

三、CGLib Bean工具

3.1 CGLib Bean工具介绍
3.2 CGLib Bean工具用法详述

四、CGLib其他用法

4.1 方法、构造器代理
4.2 Fast反射系列
4.3 Mixin
public class Test {
    public static void main(String[] args){
        ClassA classA = new ClassA();
        ClassB classB = new ClassB();
        Mixin mixin = Mixin.create(new Object[] {classA , classB});
        InterfaceA interA = (InterfaceA)mixin;
        System.out.println(interA.funcA());
        classA.setStr("changed");
        System.out.println(interA.funcA());
        InterfaceB interB = (InterfaceB)mixin;
        interB.funcB();
    }
}

interface InterfaceA {
    String funcA();
}

interface InterfaceB {
    void funcB();
}

class ClassA implements InterfaceA {
    private String str = "origin";
    
    @Override
    public String funcA() {
        return str; 
    }
    
    public void setStr(String str) {
        this.str = str;
    }
}

class ClassB implements InterfaceB{
    @Override
    public void funcB() {
        System.out.println("funcB");
    }
    
}

Mixin#create会抽取出被绑定的对象们的接口,然后在新类中实现,也就是说CGLib不会添加那些不在接口中定义的方法,CGLib也不会把被绑定对象们的字段添加到新类之中,所以只能称之为逻辑上的合并
--------------------------------
结果:
origin
changed
funcB

public class Test {
    public static void main(String[] args) throws Exception{
        SampleBean sampleBean = new SampleBean();
        sampleBean.setName("snmutsuki");
        OtherSampleBean otherSampleBean = new OtherSampleBean();
        otherSampleBean.setName("yoom");
        otherSampleBean.setAge(16);
        Mixin mixin = Mixin.createBean(new Object[] {sampleBean , otherSampleBean});
        System.out.println(mixin.getClass().getDeclaredMethod("getName").invoke(mixin));
        BeanMap beanMap = BeanMap.create(mixin);
        System.out.println(beanMap);
    }
}

Mixin#createBean会抽取被绑定Bean的Setter和Getter方法,遇到同名的Setter和Getter方法则忽略当前这个Setter和Getter方法以上一个为准,同样地,该新类也不会合并属性字段
----------------------------------
结果:
snmutsuki
{name=snmutsuki, age=16}

4.4 其他

五、注意事项及说明


参考文档:
[1] CGLib: The Missing Manual
[2] https://github.com/cglib/cglib/wiki/How-To

上一篇 下一篇

猜你喜欢

热点阅读