/**
* A FactoryBean implementation that
* returns a value which is an ObjectFactory
* that in turn returns a bean sourced from a BeanFactory.
*
* As such, this may be used to avoid having a client object directly calling BeanFactory#getBean(String) to get
* a (typically prototype) bean from a BeanFactory, which would be a
* violation of the inversion of control principle.
*/
public class ObjectFactoryCreatingFactoryBean extends AbstractFactoryBean {
private String targetBeanName;
/**
* Set the name of the target bean.
* <p>The target does not <i>have</> to be a prototype bean, but realisticially
* always will be (because if the target bean were a singleton, then said
* singleton bean could simply be injected straight into the dependent object,
* thus obviating the need for the extra level of indirection afforded by
* the approach encapsulated by this class). Please note that no exception
* will be thrown if the supplied <code>targetBeanName</code> does not
* reference a prototype bean.
*/
public void setTargetBeanName(String targetBeanName) {
this.targetBeanName = targetBeanName;
}
public void afterPropertiesSet() throws Exception {
Assert.hasText(this.targetBeanName, "Property 'targetBeanName' is required");
super.afterPropertiesSet();
}
public Class getObjectType() {
return ObjectFactory.class;
}
protected Object createInstance() {
return new ObjectFactory() {
public Object getObject() throws BeansException {
return getTargetBean(targetBeanName);
}
};
}
/**
* Template method for obtaining a target bean instance.
* Called by the exposed ObjectFactory's <code>getObject()</code> method.
* @param targetBeanName the name of the target bean
* @return the target bean instance
*/
protected Object getTargetBean(String targetBeanName) {
return getBeanFactory().getBean(targetBeanName);
}
}