Подтвердить что ты не робот

Как ввести FactoryBean вместо объекта, который он производит?

Скажем, у меня есть следующий Spring config (версия Spring равна 3.0.3):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans.xsd">

   <bean id="theFactoryBean" class="wax.MyFactoryBean"/>

   <bean id="factoryBeanUser" class="wax.FactoryBeanUser">
       <!-- what should be placed here?-->
   </bean>

</beans>

У меня есть экземпляр реализации FactoryBean и некоторый другой экземпляр. Мне нужно Spring, чтобы ввести другой экземпляр FactoryBean, а не объект, который он создает.

Существует два возможных способа решения этой проблемы.

Первый, очевидный и неисправный:

 <bean id="factoryBeanUser" class="wax.FactoryBeanUser">
    <property name="myFactoryBean" ref="&theFactoryBean"/>
</bean>

С этой конфигурацией Spring в начале запускается следующее исключение:

    [skipped irrelevant part]
Caused by: org.xml.sax.SAXParseException: The reference to entity "theFactoryBean" must end with the ';' delimiter.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:174)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:388)
at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1414)

Я нашел это решение Spring: получая объект FactoryBean вместо FactoryBean.getObject(), этот вопрос решается в ответ, и за него проголосовали четыре человека. Поэтому я предполагаю, что это решение может работать, но в настоящее время что-то не так в моем коде.

Второй, работающий, но неудобный:

public class FactoryBeanUser implements ApplicationContextAware{

private MyFactoryBean myFactoryBean;

   public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        myFactoryBean = (MyFactoryBean)applicationContext.getBean("&theFactoryBean");
   }
}

Мой вопрос: возможно ли сделать первый подход функциональным, или я должен придерживаться второго пути?

4b9b3361

Ответ 1

Кажется, что синтаксический анализатор XML интерпретирует амперсанд (&) как начало XML-объекта. Вы можете попробовать использовать ref="&amp;theFactoryBean".

spring docs неясно, разрешен ли этот синтаксис в XML файле или только с программным поиском. Но тогда xml-конфигурация используется контекстом приложения, поэтому я предполагаю, что &amp; должен работать (хотя кажется, что это не лучший выбор для специального символа)

Вот почему я предлагаю другое: если вам действительно нужен factory bean, а не его продукт, создайте еще один bean, который не реализует FactoryBean, определите метод createObject() или что-то еще как это, и использовать его на всех фабриках, которые в нем нуждаются.

Sidenote - лучше использовать xsd с включенной версией:

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd