• 有趣的BUG之Stack Overflow


    今天遇到一个很有意思的bug,当程序开发完成后打包到服务器运行,总是会出现栈溢出异常,经过排查发现,问题出现在一个接口上,但这个接口逻辑并不复杂,除了几局逻辑代码外和打印语句之外也没有其他的了,但是只要调用这个接口就马上会出现栈溢出的异常,随后对代码进行了排查,最后发现问题居然出现在日志打印语句上。

    平常在开发过程中我们经过会通知打印日志来了解程序的运行状态,没想到今天在这上面翻了车,这个打印语句是打印一个对象,我们知道,当要打印一个对象的时候会自动调用对象的toString()方法,项目中我们会使用lombok插件来帮助我们生成对应的get、set、equals、hashcode、toString等方法,而打印的这个对象在由Spring容器管理的一个bean,我们给这个bean取名A,在A里面又依赖注入了另一个bean,我们取名B,A和B形成了循环依赖,且都重写了toString方法,所以当调用A的toString方法时,会调用B的toString方法,当调用B的toString又会调用A的toString,由此形成了死循环,最终导致了栈溢出的异常。
    下面是我精简出的出现问题的代码结构,帮助大家避坑
    类A结构

    java
    public class A {
    
        private B b;
    
        public B getB() {
            return b;
        }
    
        public void setB(B b) {
            this.b = b;
        }
    
        @Override
        public String toString() {
            return "A{" +
                    "b=" + b +
                    '}';
        }
    }

    类B结构

    java
    public class B {
    
        private A a;
    
        public A getA() {
            return a;
        }
    
        public void setA(A a) {
            this.a = a;
        }
    
        @Override
        public String toString() {
            return "B{" +
                    "a=" + a +
                    '}';
        }
    }

    Spring配置文件,类A类B交给容器管理

    xml
    <bean id="a" class="com.zlm.bean.A">
        <property name="b" ref="b"/>
    </bean>
    <bean id="b" class="com.zlm.bean.B">
        <property name="a" ref="a"/>
    </bean>

    主程序

    java
    public class App {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext xmlApplicationContext = new ClassPathXmlApplicationContext("bean.xml");
            A bean = xmlApplicationContext.getBean(A.class);
            // 会报错
            System.out.println(bean);
        }
    }

    错误信息

    highlighter- julia
    Exception in thread "main" java.lang.StackOverflowError

    __EOF__

  • 本文作者: Liming_Code
  • 本文链接: https://www.cnblogs.com/lm66/p/16301220.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    docker镜像run后 ps命令查不到解决办法;docker 容器显示exit(1)
    全平台数据(数据库)管理工具 DataCap 管理 Rainbond 上的所有数据库
    设置模式之工厂模式
    行业洞察 | 新零售业态下,品牌电商应如何重塑增长?
    Synchronized 原 理
    ES6深入(Symbol、类、迭代器、Set、Map)(二)
    jQuery对于链和捕获的实战研究
    R语言Sys.Date函数获取当前日期、使用seq函数创建日期序列(指定起始日期和结束日期)、length.out参数指定生成的日期序列的长度
    云主机生成和绑定密钥
    如何保护PayPal账户安全:防止多个PayPal账号关联?
  • 原文地址:https://www.cnblogs.com/lm66/p/16301220.html