依赖

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

简介

CGLIB(Code Generator Library)是一个强大的、高性能的代码生成库。
其被广泛应用于AOP框架(Spring)中,用以提供方法拦截操作。 CGLIB代理主要通过对字节码的操作,以控制对象的访问。
CGLIB底层使用了ASM(一个短小精悍的字节码操作框架)来操作字节码生成新的类。 CGLIB相比于JDK动态代理更加强大:
JDK动态代理虽然简单易用,但只能对接口进行代理。
如果要代理的类为一个普通类,没有接口,那么Java动态代理就没法使用了。 Java动态代理使用Java原生的反射API进行操作(运行期),在生成类上比较高效。
CGLIB使用ASM框架直接对字节码进行操作(编译期),在类的执行过程中比较高效

Enhancer 介绍

Enhancer:
Enhancer既能够代理普通的class,也能够代理接口。
Enhancer创建一个被代理对象的子类并且拦截所有的方法调用(包括从Object中继承的toString和hashCode方法)。
Enhancer不能够拦截final类与方法。 Enhancer.setSuperclass(Class superclass);
用来设置父类型 Enhancer.setCallback(Callback callback);
Enhancer.setCallback(new InvocationHandler(){});
Enhancer.setCallback(new MethodInterceptor(){});
增强 Enhancer.create(Class type, Callback callback);
Enhancer.create(Class superclass, Class[] interfaces, Callback callback);
Enhancer.create(Class[] argumentTypes, Object[] arguments);
方法是用来创建代理对象,其提供了很多不同参数的方法用来匹配被增强类的不同构造方法。

Callback

Callback是一个空的接口,在Cglib中它的实现类有以下几种:
MethodInterceptor
NoOp
LazyLoader
Dispatcher
InvocationHandler
FixedValue MethodInterceptor: 它可以实现类似于AOP编程中的环绕增强(around-advice)。 它只有一个方法:
public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args, MethodProxy proxy) 代理类的所有方法调用都会转而执行这个接口中的intercept方法而不是原方法。
如果需要在intercept方法中执行原方法可以使用参数method进行反射调用,
或者使用参数proxy 一 proxy.invokeSuper(obj, args);
后者会快一些(反射调用比正常的方法调用的速度慢很多)。
MethodInterceptor允许我们完全控制被拦截的方法,并且提供了手段对原方法进行调用, 因为 MethodInterceptor的效率不高,它需要产生不同类型的字节码,
并且需要生成一些运行时对象(InvocationHandler就不需要),所以Cglib提供了其它的接口供我们选择。 InvocationHandler:
它的使用方式和MethodInterceptor差不多。
需要注意的一点是,所有对invoke()方法的参数proxy对象的方法调用都会被委托给同一个InvocationHandler,
所以可能会导致无限循环。 NoOp:
这个接口只是简单地把方法调用委托给了被代理类的原方法,
不做任何其它的操作。 LazyLoader,它也提供了一个方法:
Object loadObject()
loadObject()方法会在第一次被代理类的方法调用时触发,它返回一个代理类的对象,
这个对象会被存储起来然后负责所有被代理类方法的调用,一种lazy模式。
如果被代理类或者代理类的对象的创建比较麻烦,而且不确定它是否会被使用,那么可以选择使用这种lazy模式来延迟生成代理。 Dispatcher:
Dispatcher和LazyLoader接口相同,也是提供了loadObject()方法。
不过它们之间不同的地方在于,
Dispatcher的loadObject()方法在每次发生对原方法的调用时都会被调用并返回一个代理对象来调用原方法。
也就是说Dispatcher的loadObject()方法返回的对象并不会被存储起来, 可以类比成Spring中的Prototype类型,而LazyLoader则是lazy模式的Singleton。

ImmutableBean 不可变Bean

ImmutableBean允许创建一个原来对象的包装类,
这个包装类是不可变的,任何改变底层对象的包装类操作都会抛出IllegalStateException。 SampleBean bean = new SampleBean();
bean.setValue("Hello world"); SampleBean immutableBean = (SampleBean) ImmutableBean.create(bean); //创建不可变类 immutableBean.setValue("Hello cglib"); //直接修改将throw exception bean.setValue("Hello world, again"); //可以通过底层对象来进行修改

BeanGenerator

运行时动态的创建一个bean

    BeanGenerator beanGenerator = new BeanGenerator();
beanGenerator.addProperty("value",String.class);
Object myBean = beanGenerator.create(); Method setter = myBean.getClass().getMethod("setValue",String.class);
setter.invoke(myBean,"Hello cglib"); Method getter = myBean.getClass().getMethod("getValue");

BeanCopier

从一个bean复制到另一个bean中,还提供了一个转换器,用来在转换的时候对bean的属性进行操作。

BeanCopier.create(Class source, Class target, boolean useConverter)

    BeanCopier copier = BeanCopier.create(Bean1.class, Bean2.class, false);  //设置为true,则使用converter

    Bean1 bean1 = new Bean1();
bean1.setValue("Hello cglib");
Bean2 bean2 = new Bean2();
copier.copy(bean1, bean2, null); //设置为true,则传入converter,指明怎么进行转换

BeanMap

BeanMap类实现了Java Map,将一个bean对象中的所有属性转换为一个<String,Obejct>的Java Map

    BeanMap map = BeanMap.create(bean); //将对象转为BeanMap

public abstract class BeanMap implements Map {

    protected Object bean;

    public Object get(Object key) {
return this.get(this.bean, key);
} public Object put(Object key, Object value) {
return this.put(this.bean, key, value);
} public void setBean(Object bean) {
this.bean = bean;
} public Object getBean() {
return this.bean;
}
}

参考

https://blog.csdn.net/danchu/article/details/70238002

https://blog.csdn.net/Q_AN1314/article/details/79724334

CGLIB 详解的更多相关文章

  1. JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解

    在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...

  2. 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理

    Spring AOP详解 . JDK动态代理.CGLib动态代理  原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...

  3. JDK、CGlib动态代理详解

    Java动态代理之JDK实现和CGlib实现(简单易懂)      一 JDK和CGLIB动态代理原理 1.JDK动态代理 利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生 ...

  4. 静态代理,动态代理,Cglib代理详解

    一.静态代理 新建一个接口 定义一个玩家方法: package com."".proxy.staticc; public interface Iplayer { public vo ...

  5. 代理模式详解:静态代理+JDK/CGLIB 动态代理实战

    1. 代理模式 代理模式是一种比较好的理解的设计模式.简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标 ...

  6. Spring框架系列(11) - Spring AOP实现原理详解之Cglib代理实现

    我们在前文中已经介绍了SpringAOP的切面实现和创建动态代理的过程,那么动态代理是如何工作的呢?本文主要介绍Cglib动态代理的案例和SpringAOP实现的原理.@pdai Spring框架系列 ...

  7. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  8. Spring 3.x jar 包详解 与 依赖关系

    以下的内容我会持续更新(当然是我有新发现的时候); 以下内容是我在网上搜索.整理.修改的而成的内容.由于很多内容都是转载了,无法追溯到源头,因此无法一一对原作者进行道谢. 这几天,我查阅大量的官方的文 ...

  9. Spring 3.x jar 包详解 与 依赖关系(转)

    以下的内容我会持续更新(当然是我有新发现的时候); 以下内容是我在网上搜索.整理.修改的而成的内容.由于很多内容都是转载了,无法追溯到源头,因此无法一一对原作者进行道谢. 这几天,我查阅大量的官方的文 ...

随机推荐

  1. MySQL索引与事务

    MySQL索引与事务 链接:https://pan.baidu.com/s/1ANGg3Kd_28BzQrA5ya17fQ 提取码:ekpy 复制这段内容后打开百度网盘手机App,操作更方便哦 1.索 ...

  2. JDBC getConnection细节

    https://blog.csdn.net/luanlouis/article/details/29850811 概述             一般情况下,在应用程序中进行数据库连接,调用JDBC接口 ...

  3. dubbo-源码阅读之Filter实现原理

    最近完成一个需求,使用阿里Arms需要在log里面加上traceId,但是发现dubbo异常 被ExceptionFilter捕获 并打印  打印不出traceI,然后百度搜索如何重写Filter 参 ...

  4. 一些笔记jexcel

    根据坐标或者指定列标题 jexcel.getColumnNameFromId([ x, y ]);

  5. printf函数与缓冲区

    printf函数与缓冲区 printf函数是一个行缓冲函数,先将内容写到缓冲区,满足一定条件后,才会将内容写入对应的文件或流中. 基本条件如下: .缓冲区填满 .写入的字符中有‘\n’ '\r' .调 ...

  6. Spring boot ----RestTemplate学习笔记

    ****spring boot-----restTemplate 封装了HttpURLConnection,HttpClient,Netty等接口访问实现库 restTemplet包含以下部分 Htt ...

  7. hdu 5792 线段树+离散化+思维

    题目大意: Given a sequence A with length n,count how many quadruple (a,b,c,d) satisfies: a≠b≠c≠d,1≤a< ...

  8. Delphi 常用API 函数列表

    Delphi 常用API 函数 AdjustWindowRect 给定一种窗口样式,计算获得目标客户区矩形所需的窗口大小AnyPopup 判断屏幕上是否存在任何弹出式窗口ArrangeIconicWi ...

  9. 【Dart学习】-- Dart之extends && implements && with的用法与区别

    一,概述 继承(关键字 extends) 混入  mixins (关键字 with) 接口实现(关键字 implements) 这三种关系可以同时存在,但是有前后顺序: extends -> m ...

  10. python培训拾遗

    20140421 1. 三大利器: dir----列出所有内部方法 a=1 dir(a) 可以列出所有内部方法,就是带两个下划线的:带一个下划线的是普通方法 help---查看帮助 help(a.bi ...