Let's say I have following Spring config (version of Spring is 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>
I have instance of FactoryBean
implementation and some other instance. I need Spring to inject to other instance FactoryBean
, not the object it produces.
There are two possible ways to solve it.
First one, obvious and malfunctional:
<bean id="factoryBeanUser" class="wax.FactoryBeanUser">
<property name="myFactoryBean" ref="&theFactoryBean"/>
</bean>
With this config Spring throws following exception on start:
[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)
I found this solution Spring: Getting FactoryBean object instead of FactoryBean.getObject(), this question is maked as answered and four people voted for it. So I assume that this solution might work, but currently there is something wrong in my code.
Second one, working but awkward:
public class FactoryBeanUser implements ApplicationContextAware{
private MyFactoryBean myFactoryBean;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
myFactoryBean = (MyFactoryBean)applicationContext.getBean("&theFactoryBean");
}
}
My question is it possible to make first approach functional or I should stick with a second way?
Let's discuss the three methods: getObject() – returns an object produced by the factory, and this is the object that will be used by Spring container. getObjectType() – returns the type of object that this FactoryBean produces. isSingleton() – denotes if the object produced by this FactoryBean is a singleton.
To create a factory bean, all you have to do is to implement the FactoryBean interface by your creator bean class which will be creating actual other beans. Or to keep it simple, you can extend AbstractFactoryBean class.
Factory-method is used for calling a static method to create object in same bean class. Factory-bean is used for creating a object based on factory design pattern.
3.3.2.3 Instantiation using an instance factory method Similar to instantiation through a static factory method, instantiation with an instance factory method invokes a non-static method of an existing bean from the container to create a new bean.
It seems the XML parser interprets the ampersand (&) as a start of an XML-entity. You can try using ref="&theFactoryBean"
.
The spring docs is not clear whether this syntax is allowed in an xml file, or only with programatic lookup. But then the xml configuration is used by the app context, so I assume the &
should work (although it seems it has not been the best choice for a special symbol)
Here's why I'd suggest another thing - if you really need the factory bean rather than its product, create another bean, that does not implement FactoryBean
, define a method createObject()
or something like that, and use it in all factories that need it.
A sidenote - better reference the xsd with the version included:
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With