我有一个现有的弹簧(5.3.9)转换器.它是一个无状态转换器:没有成员,默认构造函数为空.使用此表单,它会被选中,并与我的系统配合良好:

class Conv implements Converter<A, B> {
    public B convert(A a) {
    ...
    }
}

向该转换器添加状态时(对另一个bean的任何引用):

class Conv implements Converter<A, B> {
    // the state
    private final X x; 

    public Conv(X x) {
        this.x = x;
    }
    public B convert(A a) {
    ...
    }
}

The Problem:现在,转换器cannot be found at runtime:

未找到能够从类型[A]转换为类型[B]的转换器

转换器本身可以成功创建,并且仍然由生命周期进行 Select .依赖关系被很好地注入,并且它存在(位于构造函数内部的调试中).bean初始化过程中没有任何异常.

最后,在与同事讨论后,他建议在构造器的论点中增加@Lazy:

class Conv implements Converter<A, B> {
        // the state
        private final X x; 
    
        public Conv(@Lazy X x) {
            this.x = x;
        }
        public B convert(A a) {
        ...
        }
    }

令人惊讶的是,它解决了这个问题!现在可以在添加状态之前找到并使用转换器.

(update:我无法创建一个再现此问题的最小示例.它可能与我真正的beans依赖性有关……).

你能解释为什么@Lazy会耍这个把戏吗?

推荐答案

问题是Converter需要在生命周期的某个时间注册.向其添加依赖项改变了可以创建此转换器的点.

现在,当添加@Lazy时,可以在正确的时间再次进行构造,因为依赖关系现在仅在使用依赖关系时使用/检测.@Lazy将作为依赖关系的代理,在使用时将执行ApplicationContext.getBean调用,而不是在构造对象时.

因此,基本上它与上下文生命周期中的何处可以构造对象有关,如果可以使用或不使用.

Java相关问答推荐

如何从片段请求数据到活动?在主要活动中单击按钮请求数据?

在Java中测试DAO方法:假实现与内存数据库

Spark上下文在向Spark提交数据集时具有内容,但Spark在实际构建它时发现它为空

如何在Java中从XML中获取特定的 node ,然后将其删除?

对于亚洲/香港,使用ResolverStyle.STRICT的LocalDate.parse返回意外结果

如何在Spring Java中从数据库列中获取JSON中的具体数据

带错误BER验证的itext8签名返回pdf

用户填充的数组列表永不结束循环

根本不显示JavaFX阿拉伯字母

Java 11 HttpCookie.parse在解析包含JSON的Cookie时引发IlLegalArgumentException

错误:未找到扩展元素在JBossEAP 7.2中安装FUSE时出错

如何获得凌空cookies ,并设置它在下一个请求- android

寻找Thread.sky()方法的清晰度

向Java进程发送`kill-11`会引发NullPointerException吗?

有没有办法知道在合并中执行了什么操作?

在Oracle中调用输出参数在索引处缺少IN或OUT参数的函数

我无法在我的Spring Boot应用程序中导入CSV依赖项

如何在Spring Boot Auth服务器上正确配置CORS?

Intellij 2023 IDE:始终在顶部显示菜单栏

如何在特定关键字后提取与模式匹配的多个值?