【问题标题】:constructor-arg and property together in bean definitionbean定义中的constructor-arg和property
【发布时间】:2011-07-06 05:32:11
【问题描述】:
<bean id="cObject" scope="request" class="x.y.z.CClass"/>
<bean id="bObject" scope="request" class="x.y.z.BClass"/>
<bean id="aObject" scope="request" class="x.y.z.AClass">
    <constructor-arg ref="bObject" />
    <property name="cRef" ref="cObject" />
</bean>

aObject.cRef 由于某种原因未设置。请注意,constructor-arg 和 property 在同一个定义中使用。我还没有看到具有类似功能的示例/帖子。

【问题讨论】:

  • 哪个版本的 Spring?使用 Spring 3.0.5 对我来说效果很好。另外,请尝试仅设置其中一个。我的猜测是您的问题与混合属性和构造函数参数无关。
  • 这个语法很好。你确定你没有尝试使用 within 构造函数中的cRef,因为那时它还没有被设置。
  • 以单个小写字母开头的 bean 可能会导致 Spring、Jackson 和其他依赖 bean 规范的问题。如果您将属性更改为 myCRef 是否可以解决问题?

标签: java spring properties javabeans


【解决方案1】:

混合&lt;constructor-arg&gt;&lt;property&gt; 通常是个坏主意。

使用&lt;constructor-arg&gt; 的原因只有一个,那就是创建不可变对象。

但是,如果您可以设置对象的属性,您的对象就不是不可变的。不要使用&lt;constructor-arg&gt;。重新设计类,如果您需要在创建 bean 时应用一些逻辑,请使用带有 @PostConstruct 注释的初始化方法。

【讨论】:

  • 那是有道理的。通过使用 autowire="byName" 和属性修复。不知何故,当 struts 实例化 bean 时,它没有使用自定义构造函数调用 bean。这个修复更可取。
【解决方案2】:

我的同事发现的相同来源:

Caused by: org.springframework.beans.factory.BeanCreationException:
  Error creating bean with name 'service.MenuService#0'
  defined in class path resource [spring-beans/integrator.xml]:
  Could not resolve matching constructor (hint: specify index/type/name
  arguments for simple parameters to avoid type ambiguities)

而我的主机、测试和生产服务器没有这样的错误。

与:

<bean class="service.MenuService">
    <constructor-arg index="0" type="java.lang.String" value="#{user}"/>
    <constructor-arg index="1" type="java.lang.String" value="#{password}"/>
    <constructor-arg index="2" type="java.lang.String" value="#{uri}"/>
    <property name="system" value="OPRT"/>
    <property name="client" value="OPRT"/>
</bean>

虽然 bean 中只有一个 3-args 构造函数。

使用构造函数的原因 - 它通过调用init() 方法对非 Spring 库执行一些附加操作。并将 args 设置为字段。

所以我把spring-beans.xml改成:

<bean class="service.MenuService" init-method="init">
    <property name="login" value="#{user}"/>
    <property name="password" value="#{password}"/>
    <property name="httpsUrl" value="#{uri}"/>
    <property name="system" value="OPRT" />
    <property name="client" value="OPRT" />
</bean>

关注init-method= 部分。

更新 毕竟我编写了简单的 XML 配置并在调试器中逐步执行 Spring 源代码。似乎使用 Spring 3.x 可以在 XML bean 定义中结合 constructor-argproperty (检查 doCreateBeanAbstractAutowireCapableBeanFactory.java 中,接下来调用 createBeanInstancepopulateBean)。

另见https://softwareengineering.stackexchange.com/questions/149378/both-constructor-and-setter-injection-together-in-spring/

【讨论】:

    猜你喜欢
    • 2020-02-27
    • 1970-01-01
    • 2018-08-15
    • 2015-05-16
    • 1970-01-01
    • 1970-01-01
    • 2013-06-20
    • 2014-01-20
    • 1970-01-01
    相关资源
    最近更新 更多