【问题标题】:Setter Injection not working with factory method injection of SpringSetter Injection 不适用于 Spring 的工厂方法注入
【发布时间】:2014-01-07 12:39:00
【问题描述】:

我有两个 bean,SimpleBean 和 ArgumentBean,我正在尝试通过工厂方法连接 bean,并尝试在相同的 bean 定义中替换 bean(我知道这样做很糟糕,但我只是在做一个实验)

即我有以下工厂实用程序类:

    public class FactoryClassUtils {

    public static ArgumentBean getArgumentBean(String firstArg, int secondArg) {
        return new ArgumentBean(firstArg, secondArg);
    }

    public static SimpleBean getSimpleBean(ArgumentBean firstArg, int secondArg) {
        return new SimpleBean(firstArg, secondArg);
    }

    }

下面提到的配置已经在spring config xml中指定:

        <bean name="argumentBean" class="com.view.spring.factory.factoryclasses.FactoryClassUtils"
        factory-method="getArgumentBean">
        <constructor-arg type="java.lang.String" index="0" value="Hey All!!!" />
         <constructor-arg type="int" index="1" value="20" />
    </bean>

    <bean name="simpleBean"
        class="com.view.spring.factory.factoryclasses.FactoryClassUtils"factory-method="getSimpleBean">
        <constructor-arg>
        <bean class="com.tcs.view.spring.dataobjects.ArgumentBean"/>
        </constructor-arg>
        <constructor-arg type="int" value="20" />
        <property name="argumentBean" ref="argumentBean" /> 
    </bean> 

我在上面执行时收到此错误:

    Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'argumentBean' of bean class [com.view.spring.dataobjects.SimpleBean]: Bean property 'argumentBean' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
    at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:805)
    at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:655)

值得一提的是,所有的 getter 和 setter 都存在于两个 bean 中。 SimpleBean.java 具有类型 ArgumentBean.java 的属性。

Simple Bean 的定义是:

 package com.view.spring.dataobjects;
 public class SimpleBean {
    private ArgumentBean argumentBean;
    int argumentCount;

    public ArgumentBean getArgument() {
        return argumentBean;
    }

    public void setArgument(ArgumentBean argumentBean) {
        this.argumentBean= argumentBean;
    }

    public int getArgumentCount() {
        return argumentCount;
    }

    public void setArgumentCount(int argumentCount) {
        this.argumentCount = argumentCount;
    }

    public SimpleBean(ArgumentBean argument, int argumentCount) {
        this.argumentBean= argument;
        this.argumentCount = argumentCount;
    }

    public void letHimSay() {
        argumentBean.saySomething();
        System.out.println(this.argumentCount);
    }
}

ArgumentBean 的定义是:

package com.view.spring.dataobjects;

public class ArgumentBean {

    private String sayString;
    private int anotherArg;

    public ArgumentBean(String sayString, int anotherArg) {
        this.sayString = sayString;
        this.anotherArg = anotherArg;
    }
    public ArgumentBean(String sayString, Integer anotherArg) {
        this.sayString = sayString;
        this.anotherArg = anotherArg.intValue();
    }

    public ArgumentBean() {

    }

    public void saySomething() {
        System.out.println("We say: "+this.sayString);
        System.out.println(this.anotherArg+" times");
    }
}

如果我从 simpleBean 定义中删除属性标记,我不会收到任何错误。此标记不适用于工厂方法,但在尝试使用构造函数参数时效果很好。有人可以帮我理解这种情况吗?

【问题讨论】:

  • 请显示SimpleBean 的定义。看起来您正在尝试同时使用构造函数和 setter 注入,但您没有在任何地方显示您实际拥有 setter。
  • 嗯错误问Does the parameter type of the setter match the return type of the getter?是这样吗?
  • 工厂方法是老派。使用@Configuration 类,你可以添加所有你需要的java逻辑,而不需要任何XML
  • @chrylis 我已经编辑了我的问题以提供 SimpleBean 和 ArgumentBean 的定义
  • @Callahan 恐怕不是这样,getter 的返回类型与 setter 的参数类型匹配。

标签: java spring dependency-injection constructor-injection


【解决方案1】:

您需要在 FactoryClassUtils 类中为 argumentBean 添加一个 setter 方法

   public class FactoryClassUtils {

    private ArgumentBean argumentBean = null;

    public static ArgumentBean getArgumentBean(String firstArg, int secondArg) {
        return new ArgumentBean(firstArg, secondArg);
    }

    public static SimpleBean getSimpleBean(ArgumentBean firstArg, int secondArg) {
        return new SimpleBean(firstArg, secondArg);
    }

    public void setArgumentBean(Argumentbean argumentBean){
    this.argumentBean = argumentBean;    
    }

}

这是必需的,因为您已在 xml 中将 argumentbean 定义为 FactoryClassUtils 的属性

<bean name="simpleBean"
    class="com.view.spring.factory.factoryclasses.FactoryClassUtils"factory-method="getSimpleBean">
    <constructor-arg>
    <bean class="com.tcs.view.spring.dataobjects.ArgumentBean"/>
    </constructor-arg>
    <constructor-arg type="int" value="20" />
    <property name="argumentBean" ref="argumentBean" /> 

按照 Java 命名约定为属性放置 setter 和 getter 方法总是好的

【讨论】:

    【解决方案2】:

    感谢大家投入时间并为我提供帮助。问题解决了。问题出在我的代码上。 SimpleBean.java 中的bean 名称是argument 而不是argumentBean。我指的是变量名,但应该使用 getter 名称,除了“get”后缀(当然是第一个字母小写)。我将配置更改为以下: 解决了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-05
      • 2013-01-24
      • 2015-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多