首页 > 其他分享 >cglib 代理类自己equals自己 返回false问题

cglib 代理类自己equals自己 返回false问题

时间:2024-06-14 17:33:52浏览次数:26  
标签:Object false CGLIB arrbl args equals cglib true

问题:

通过debug发现result.removeAll的时候 删不了

public boolean equals(Object obj) {
            return obj instanceof OspSpringBoot2Initializer.OspBean && this.bean.equals(((OspSpringBoot2Initializer.OspBean)obj).bean);
        }

this.bean.equals(((OspSpringBoot2Initializer.OspBean)obj).bean 这里返回了false

明明地址一致,那为什么返回了false?

定位问题:

进一步定位。

通过debug定位到: 最终调用java.lang.Object#equals方法的时候,this和obj的引用不一致所以返回false
通过栈帧可以看到:
调用了cglib增强类的equals方法
通过arthas jad 命令反编译出cglib类的代码

public final boolean equals(Object object) {
        boolean[] arrbl = SalesNormalPoolService$$EnhancerByCGLIB$$e87bde91.$jacocoInit();
        MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
        if (methodInterceptor != null) {
            arrbl[3] = true;
        } else {
            SalesNormalPoolService$$EnhancerByCGLIB$$e87bde91.CGLIB$BIND_CALLBACKS(this);
            methodInterceptor = this.CGLIB$CALLBACK_0;
            arrbl[4] = true;
        }
        if (methodInterceptor != null) {
            boolean bl;
            Object object2 = methodInterceptor.intercept((Object)this, CGLIB$equals$0$Method, new Object[]{object}, CGLIB$equals$0$Proxy);
            if (object2 == null) {
                bl = false;
                arrbl[5] = true;
            } else {
                bl = (Boolean)object2;
                arrbl[6] = true;
            }
            arrbl[7] = true;
            return bl;
        }
        arrbl[8] = true;
        return super.equals(object);
    }

这里结果依赖于methodInterceptor.intercept((Object)this, CGLIB$equals$0$Method, new Object[]{object}, CGLIB$equals$0$Proxy);

我们继续看下intercept 这个方法

public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
			if (method.getDeclaringClass() == Object.class) {
				return method.invoke(this, args);
			}
			//.. 省略 不会走这里的
		}


发现是通过反射调用java.lang.Object#equals方法,此时是this.equals(args[0]) 发现地址不一致 结果返回false。

所以bug就定位到

method.invoke(this, args);

解决:

正确写法应该是:

methodProxy.invokeSuper(o, args);

public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
			if (method.getDeclaringClass() == Object.class) {
				return methodProxy.invokeSuper(o, args);
			}
			//.. 省略 不会走这里的
		}

修改过后

在调用java.lang.Object#equals时

传入了o 和 args[0] ,它们两个地址相同,所以返回true

我们继续看下栈帧:

现在有调用CGLIB$equals$0:-1, SalesNormalPoolService$$EnhancerByCGLIB$$e87bde91

final boolean CGLIB$equals$0(Object object) {
        boolean[] arrbl = SalesNormalPoolService$$EnhancerByCGLIB$$e87bde91.$jacocoInit();
        arrbl[2] = true;
        return super.equals(object);
    }



也就是 现在的调用是:o == args[0] → true

以前的调用是:this == args[0] → false

标签:Object,false,CGLIB,arrbl,args,equals,cglib,true
From: https://www.cnblogs.com/eiffelzero/p/18248330

相关文章

  • 创建entity模板,equals hashcode 方法模板
    创建entity模板,equalshashcode方法模板如下为FLINK官网实体类demoequalshashcode方法模板可以参考////Sourcecoderecreatedfroma.classfilebyIntelliJIDEA//(poweredbyFernFlowerdecompiler)//packageorg.apache.flink.walkthrough.common.entity;im......
  • 代理设计模式之JDK动态代理&CGLIB动态代理原理与源码剖析
    代理设计模式代理模式(Proxy),为其它对象提供一种代理以控制对这个对象的访问。如下图从上面的类图可以看出,通过代理模式,客户端访问接口时的实例实际上是Proxy对象,Proxy对象持有RealSubject的引用,这样一来Proxy在可以在实际执行RealSubject前后做一些操作,相当于是对RealSubject......
  • SpringAOP-代理方式-Cglib动态代理
    文章目录cglib动态代理cglib是基于继承的方式实现的是继承目标类从而产生代理类springaop底层使用的就是cglib的动态代理packagecom.itheima.cjlibproxy;importnet.sf.cglib.proxy.Callback;importnet.sf.cglib.proxy.Enhancer;importnet.sf.cglib.proxy.......
  • //编写一个函数,传入一个整数,将数字反转,检查数字是不是数字的2倍 果是则返回true,否
    思路:比如n=1234;那么如何获取4,应该n%10;那么如何获取3,获取3之前应该删除4,所以n/10;//40+3=43//43*10=430>430+2(432)>432*10(4320)+1r=0怎么获取40:r*10+d看代码:1publicclasstest2{2publicstaticvoidmain(String[]args){3int......
  • 【== 和 equals 的区别是什么?】
    文章目录一、==和equals()的主要区别?1、定义和性质2、比较的对象3、运行速度4、使用场景二、示例1、基本数据类型比较2、引用类型使用==比较3、引用类型使用equals()比较三、总结一、==和equals()的主要区别?在Java中,==和equals()是两个用于比较对象......
  • form.is_valid()一直为False,且form.errors.as_json()为空
    form.is_valid()一直为False且form.errors.as_json()为空。这种情况通常是由于提交的数据未能正确绑定到表单字段。为了排查这个问题,需要逐步检查以下几个方面:检查HTML表单:确保HTML表单的输入字段名称与LoginForm中的字段名称匹配。确保表单的method属性设置为POST,并且包含{......
  • 全局设置element-ui Dialog组件的close-on-click-modal属性为false
    前言element组件库的Dialog对话框默认可以通过点击modal关闭Dialog,即点击空白处弹框可关闭。属性  importElementUIfrom'element-ui'import'element-ui/lib/theme-chalk/index.css'//默认主题//全局修改默认配置,点击空白处不能关闭弹窗ElementUI.Dialog.......
  • hashCode 和 equals方法
     1. 为什么重写 equals 方法时需要重写 hashCode 方法?在Java中,equals 和 hashCode 方法的合同(contract)规定:(1)如果两个对象根据 equals 方法是相等的,那么它们的 hashCode 值必须相同。(2)如果两个对象根据 equals 方法是不相等的,那么它们的......
  • 一个基于cglib的bean copy方法
    需要guava和cglib:@NoArgsConstructor(access=AccessLevel.PRIVATE)publicclassBeanUtils{privatestaticfinalTable<Class<?>,Class<?>,BeanCopier>COPIER_TABLE=Tables.synchronizedTable(HashBasedTable.create());publicstatic<......
  • GoF之代理模式(静态代理+动态代理(JDK动态代理+CGLIB动态代理带有一步一步详细步骤))
    1.GoF之代理模式(静态代理+动态代理(JDK动态代理+CGLIB动态代理带有一步一步详细步骤))@目录1.GoF之代理模式(静态代理+动态代理(JDK动态代理+CGLIB动态代理带有一步一步详细步骤))每博一文案2.代理模式的理解3.静态代理4.动态代理4.1JDK动态代理4.1.1JDK动态代理中(获取到目......