Spring: получение объекта FactoryBean вместо FactoryBean.getObject () - PullRequest
12 голосов
/ 31 октября 2009

Короткий вопрос: Если у меня есть класс, который не поддерживает интерфейс FactoryBean, как я могу получить сам объект FactoryBean вместо FactoryBean.getObject ()?

Длинный вопрос: Я должен использовать стороннюю библиотеку на основе Spring, которая вряд ли использует интерфейс FactoryBean. Прямо сейчас я всегда должен настроить 2 бина:

<!-- Case 1-->
<bean id="XYZ" class="FactoryBean1" scope="prototype">
    <property name="steps">
        <bean class="FactoryBean2">
            <property name="itemReader" ref="aName"/>
        </bean>
    </property>
</bean>

<bean id="aName" class="com.package.ClassName1" scope="prototype">
    <property name="objectContext">
        <bean class="com.package.ABC"/>
    </property>
</bean>

<!-- Case 2-->
<bean id="XYZ2" class="FactoryBean1" scope="prototype">
    <property name="steps">
        <bean class="FactoryBean2">
            <property name="itemReader" ref="aName2"/>
        </bean>
    </property>
</bean>

<bean id="aName2" class="com.package.ClassName1" scope="prototype">
    <property name="objectContext">
        <bean class="com.package.QWE"/>
    </property>
</bean>

Фактически определение bean-компонента с именем «XYZ» (сравните с «XYZ2») никогда не изменится, но из-за заводской природы я должен скопировать код для каждой конфигурации. Определение bean-компонента с именем «aName» всегда будет новым (то есть каждая конфигурация будет иметь собственное значение objectContext).

Я бы хотел упростить настройку одного фабричного компонента (удалите «XYZ2» и избавьтесь от ссылки на «aName»):

<bean id="XYZ" class="FactoryBean1" scope="prototype">
    <property name="steps">
        <bean class="FactoryBean2"/>
    </property>
</bean>

<bean id="aName" class="com.package.ClassName1" scope="prototype">
    <property name="objectContext">
        <bean class="com.package.ABC"/>
    </property>
</bean>


<bean id="aName2" class="com.package.ClassName1" scope="prototype">
    <property name="objectContext">
        <bean class="com.package.QWE"/>
    </property>
</bean>

К сожалению, это не так просто, как я ожидал. Я предполагаю склеить фабрику (т.е. bean-компонент XYZ из примера) с необходимыми объектами (то есть "aName", "aName2") во время выполнения. Подход не работает, потому что когда я спрашиваю Spring для объекта FactoryBean, он возвращает мне FactoryBean.getObject (), который невозможно создать в тот момент из-за отсутствия значения itemReader.

Я надеюсь, что SpringSource предвидит мой случай, когда я смогу как-нибудь "зацепить" вызов FactoryBean.getObject (), чтобы предоставить все необходимые свойства во время выполнения.

Еще одна сложность, которая меня немного беспокоит, - это цепочки фабрик (Factory1 получает объект от Factory2, который я должен «зацепить» во время выполнения).

Любые идеи будут оценены.

Ответы [ 2 ]

20 голосов
/ 01 ноября 2009

Это & (амперсанд), а не символ At, см. Документацию Spring Framework: Настройка логики создания экземпляров с использованием FactoryBeans

<property name="factoryBean" ref="&amp;theFactoryBean" />
2 голосов
/ 31 октября 2009

Вы можете получить фабричный бин сам, используя синтаксис & в конфигурации весны:

<property name="factoryBean" ref="&theFactoryBean" />

вместо:

<property name="createdBean" ref="theFactoryBean" />
...