cglib

CGLIB动态代理简介

余生颓废 提交于 2020-02-10 17:51:11
一:前序 一开始对动态代理都不懂,一直心里还是很惧怕这个概念,之前也学过,学过就忘了,现在想想之所以忘了,是因为平时在开发中也不会使用到动态代理,那回过头再想想,自己已经做了六年多的开发了,那为什么还要学习这个了,今天想想也许就是技多不压身,其实只有知道的多了,才会在用到的时候,用起来,我想也有种说法是用到的时候再学也可以,但是在平时的开发中,我们很少会用到,可能是我们不知道动态代理,如果知道也许会在平时中使用它。之所以今天想做个总结是想到动态代理还是有很大的用处,只是我之前不知道。 二:CGLIB介绍 下面做个总结,动态代理里面有两种方式,一种是jdk的动态代理,一种是cglib动态代理,这里做个cglib动态代理,jdk的动态代理,将单独写个专题来介绍 CGLIB是一个强大的高性能的代码生成包,CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类,当然不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉,在引入cglibjar包后,也会导入ASMjar包 三:CGLIB实现 springboot支持的事务方式:@EnableTransactionManagement 在启动方法入口的类中添加 spring支持方式 :<aop:aspectj-autoproxy proxy-target-class=

【程序报错】Spring容器启动时报异常:Can not set field to com.sun.proxy.$Proxy

喜欢而已 提交于 2020-02-06 15:37:56
问题 1 异常信息 在Web项目中Spring容器启动的时候,报错信息为Can not set field… to com.sun.proxy.$Proxy。 2 本质 因为JDK实现动态代理业务的时候,只能针对接口进行代理。然而对于类需要进行代理,需要使用到CGLib。CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。正是由于在代码中使用了类代理,但是配置不正确,所以报错。 3 相关代码 首先是定义了一个接口: public interface CpsAccountService { /* 具体业务逻辑省略 */ } 然后编写了接口的实现类: @Service public class CpsAccountServiceImpl implements CpsAccountService { /* 具体业务逻辑省略 */ } 最后是在控制器层注解装配: @Controller @Api ( value = "CPS外部合作商相关接口" ) @RequestMapping ( value = "api/cps/*" ) public class CpsController { @Autowired private

cglib动态代理

折月煮酒 提交于 2020-02-06 05:10:08
cglib动态代理相比于JDK动态代理的的优秀之处在于它是够实现非接口的动态代理,且提供了多种回调方式,这里就将callbackFilter和MethodInterceptor两种 被代理类 package com.yangpeng.proxy; public class BookPorxyImpl { public void addBook() { System.out.println("增加图书的普通放方法"); } public void addBall() { System.out.println("增加Ball的普通放方法"); } } 提供统一的回调方式,cglib的主要回调是MethodInterceptor接口,和用于创建动态代理的Enhancer类 package com.yangpeng.proxy; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class BookProxyLib implements MethodInterceptor{ private Object target;/

@Configuration CGLIB提升特性

可紊 提交于 2020-02-06 05:10:01
今天看了下Spring的@Configuration,即java类配置bean,(这个spring3的新功能,虽然现在已经spring5了,但是这种配置bean的方式也是比较火的) 做了如下测试,发现一个现象,先说这个现象,后面用自己的理解再简单实现一下。 先说现象: 在java配置类中加@Configuration,下面的声明bean的方法,就只会被调一次,也就是初始化的时候,哪怕是下面的方法直接互相引用,返回的new的对象的构造方法也只会调一次 而如果不加@Configuration,那么下面的方法如果有相互调用,那么返回的new的对象的构造方法就会被调多次 下面是测试代码: @Configuration @ComponentScan("com.zs.cglib") //这个类作为配置类 public class CglibConfig { @Bean public TestDomain testDomain(){ return new TestDomain(); } @Bean public TestDomainTwo testDomainTwo(){ //这个方法会预先调用上一个方法 testDomain(); return new TestDomainTwo(); } } @Component("testDomain") public class TestDomain {

JDK动态代理和CGLIB动态代理

ぃ、小莉子 提交于 2020-02-06 03:18:22
JDK动态代理 //1.影星接口 package com.entity; //影星接口 public interface MovieStar { public void act();//演戏 } //2.被代理类----实现一个接口 package com.entity; //成龙 public class ChengLongStar implements MovieStar{ @Override public void act() { System.out.println("我是成龙,我会拍戏"); } } //3.代理类----实现InvocationHandler接口 package com.entity; import java.lang.reflect.InvocationHandler;//java的设计模式 import java.lang.reflect.Method; import java.lang.reflect.Proxy; //成龙的经纪人类 public class ChengLongProxy implements InvocationHandler{ //被代理的原始对象 private Object orientObject;//被代理对象 //绑定被代理对象,返回一个代理对象 public Object bind(Object obj){

20191218JDK和CGLIB动态代理区别

半腔热情 提交于 2020-02-05 09:35:03
前言 Spring代码实例:https://github.com/yihonglei/spring-study JDK动态代理实现原理(jdk8):https://blog.csdn.net/yhl_jxy/article/details/80586785 CGLIB动态代理实现原理:https://blog.csdn.net/yhl_jxy/article/details/80633194 一 JDK和CGLIB动态代理原理 1、JDK动态代理 利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生成一个实现代理接口的匿名类, 在调用具体方法前调用InvokeHandler来处理。 2、CGLIB动态代理 利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。 3、何时使用JDK还是CGLIB? 1)如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP。 2)如果目标对象实现了接口,可以强制使用CGLIB实现AOP。 3)如果目标对象没有实现了接口,必须采用CGLIB库,Spring会自动在JDK动态代理和CGLIB之间转换。 4、如何强制使用CGLIB实现AOP? 1)添加CGLIB库(aspectjrt-xxx.jar、aspectjweaver-xxx.jar、cglib-nodep-xxx.jar) 2

java 静态代理 JDK动态代理 Cglib动态代理

Deadly 提交于 2020-02-03 14:07:00
下面以一个简单的银行账户为例讲述讲述动态代理。 设计一个银行账户类,包含用户的账户余额,实现查询和更新余额功能 这个系统用了一段时间,有客户要求对账说账户余额给弄错了?因为上面没有存取款记录,最后银行不认账,客户收到了损失。银行为了避免这种现象再次发生,决定对这个系统进行修改,但是因为bankAccount太过复杂,希望在不修改bankAccount的情况下,增加日志功能。 静态代理 使用静态代理解决上面的问题。 银行要求所有模块都需要添加日志功能,这对苦逼的程序员来说真的是一个不小的工作量啊,这需要写多少个自定义的代理类???还有没有时间可以愉快的玩耍了! 动态代理 Java JDK提供了一种动态代理实现机制,不用为每一个类自己手动去编写一个代理类,它可以帮你自动生成代理类。 下面讲一下,上面用到的几个关键方法和接口: InvocationHandler接口: public interface InvocationHandler { public Object invoke(Object proxy,Method method,Object[] args) throws Throwable; } 参数说明: Object proxy:动态生成的代理类的实例 Method method:要调用的方法 Object[] args:方法调用时所需要的参数

cglib动态代理

依然范特西╮ 提交于 2020-02-03 01:51:12
jdk动态代理要求委托类需要实现接口,对于一些不实现任何接口的类可以使用cglib动态代理。 使用cglib动态代理需要导入需要的jar包,Spring Core包中已经集成了cglib所需要的jar包。 1、在项目目录下新建一个文件夹,取名lib 2、向lib中添加jar包 3、右击jar包->Build Path->Add to Build Path //Human类,不实现任何接口 class Human{ public void eat() { System.out.println("吃"); } //创建代理对象 public Human createProxy() { MyInterceptor cp=new MyInterceptor(); //创建动态类对象 Enhancer eh=new Enhancer(); //将需要增强的类设置为其父类 eh.setSuperclass(this.getClass()); //设置代理逻辑对象,即由这个对象(cp)来处理对真实对象方法的调用 eh.setCallback(cp); //返回代理对象 return (Human)eh.create(); } } class MyInterceptor implements MethodInterceptor{ //通过intercept方法完成对真实对象方法的调用

动态代理jdk和cglib的区别

家住魔仙堡 提交于 2020-02-01 19:08:35
动态代理的描述在前两篇文章已经做了一部分描述 动态代理的详细解读 和 动态代理的简单描述 , JDK的动态代理只能针对实现了接口的类生成代理。而cglib的动态代理是针对类实现代理,这两种代理我们可以灵活使用。 我们通过汽车跑的例子来解读这两种动态代理。 一.JDK动态代理 Car接口 package proxy; public interface Car { public void run(); } Car实现类 package proxy; public class CarImpl implements Car{ public void run() { System.out.println("car running"); } } Car代理类 package proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; //JDK动态代理代理类 public class CarHandler implements InvocationHandler{ //真实类的对象 private Object car; //构造方法赋值给真实的类 public CarHandler(Object obj){ this.car = obj; } //代理类执行方法时,调用的是这个方法

了解Spring中常见的设计模式-------------------代理模式

拜拜、爱过 提交于 2020-01-28 05:25:29
代理模式(Proxy Pattern) 指为其他对象提供一种代理,以控制对这个对象的访问。 代理对象在客服端和目标对象之间起到中介作用 属于结构型设计模式。 适用场景:保护目标对象,增强目标对象 静态代理:显示声明被代理对象 动态代理:动态配置和替换被代理对象 无法代理final修饰的方法 静态代理 代理类与被代理类属于(1:1)一对一的关系,被代理类新增了某个方法,代理类也需要进行相应的修改,不符合开闭原则。 public interface Person { void saleHouse(); void getName(); } public class HousHolder implements Person { @Override public void saleHouse() { System.out.println("houseHolder sale house"); } @Override public void getName() { System.out.println("the name of house"); } } public class HouseSaler implements Person { private HousHolder housHolder; public HouseSaler(HousHolder housHolder) { this