Setter Injection не работает с инъекцией фабричного метода Spring

У меня есть два 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 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)

Стоит отметить, что все геттеры и сеттеры присутствуют в обоих компонентах. SimpleBean.java имеет свойство типа ArgumentBean.java.

Определение простого компонента:

 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. Этот тег не работает с фабричными методами, но хорошо работает с аргументами конструктора. Может ли кто-нибудь помочь мне в понимании этой ситуации?


person Atul Kumar    schedule 07.01.2014    source источник
comment
Пожалуйста, покажите определение для SimpleBean. Похоже, вы пытаетесь использовать инъекцию как конструктора, так и сеттера, и вы нигде не показали, что у вас действительно есть сеттер.   -  person chrylis -cautiouslyoptimistic-    schedule 07.01.2014
comment
Ну ошибка спрашивает Does the parameter type of the setter match the return type of the getter? Так ли это?   -  person Callahan    schedule 07.01.2014
comment
Заводские методы — это старая школа. Используйте классы @Configuration, и вы сможете добавить всю необходимую вам логику Java без XML.   -  person Sean Patrick Floyd    schedule 07.01.2014
comment
@chrylis Я отредактировал свой вопрос, чтобы дать определение как SimpleBean, так и ArgumentBean.   -  person Atul Kumar    schedule 08.01.2014
comment
@Callahan Боюсь, это не так, тип возвращаемого значения геттера совпадает с типом параметра установщика.   -  person Atul Kumar    schedule 08.01.2014


Ответы (2)


Вам нужно добавить метод установки для argumentsBean в вашем классе FactoryClassUtils

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

}

Это необходимо, так как вы определили argumentsbean как свойство FactoryClassUtils в вашем xml.

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

person Keerthivasan    schedule 07.01.2014

Спасибо всем за то, что уделили мне время и помогли мне. Проблема решена. Проблема была с моим кодом. Имя компонента в SimpleBean.java — это аргумент, а не argumentsBean. Я имел в виду имя переменной, но должно идти с именем получателя, кроме суффикса «получить» (конечно, с маленькой буквы). Я изменил конфигурацию на следующую: ‹ свойство name="argument" ref="argumentBean" /> и это решило проблему.

person Atul Kumar    schedule 08.01.2014