java 构造函数参数和属性一起在 bean 定义中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5150181/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 09:42:51  来源:igfitidea点击:

constructor-arg and property together in bean definition

javaspringpropertiesjavabeans

提问by anthos

<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 is not getting set for some reason. Note that constructor-arg and property are used in the same definition. I have not seen an example / post with similar feature.

aObject.cRef 由于某种原因未设置。请注意,构造函数参数和属性在同一定义中使用。我还没有看到具有类似功能的示例/帖子。

回答by Sean Patrick Floyd

Mixing <constructor-arg>and <property>is generally a bad idea.

混合<constructor-arg><property>通常是一个坏主意。

There is only one good reason for using <constructor-arg>, and that is to create immutable objects.

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

However, your objects are not immutable if you can set their properties. Don't use <constructor-arg>. Redesign the class, use an initializer method annotated with @PostConstructif you need to apply some logic at bean creation time.

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

回答by gavenkoa

On same sources my colleague discover:

我的同事在同一来源发现:

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)

while my host, test and production servers have no such error.

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

With:

和:

<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>

while there are only one 3-args constructor in bean.

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

The reason to use constructor - it perform some additional actions on non-Spring library by invoking init()method. And set args as fields.

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

So I change spring-beans.xmlto:

所以我改成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>

Take attention to init-method=part.

注意init-method=部分。

UPDATEAfter all I wrote simple XML config and step through Spring source code in debugger. Seems that with Spring 3.x it's possible to combine constructor-argand propertyin XML beandefinition (check doCreateBeanin AbstractAutowireCapableBeanFactory.java, which call createBeanInstanceand populateBeannext).

更新毕竟我编写了简单的 XML 配置并在调试器中逐步执行 Spring 源代码。似乎使用 Spring 3.x 可以在 XML bean定义中组合构造函数参数属性(检查doCreateBeanin ,接下来调用createBeanInstancepopulateBean)。AbstractAutowireCapableBeanFactory.java

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

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