FactoryBean可用于以编程方式创建可能需要复杂实例化逻辑的对象。
但是,似乎FactoryBean
创建的bean 并未成为弹簧管理。这种解释是否正确?如果是这样,有什么好的解决方法吗?包含一个简短的代码示例来说明我的问题。
的ApplicationContext:
<bean id="searcher" class="some.package.SearcherFactory" />
<bean id="service" class="some.package.Service" />
工厂实施:
public class SearcherFactory implements FactoryBean<Searcher> {
@Override
public Searcher getObject() throws Exception {
return new Searcher(); // not so complex after all ;)
}
@Override
public Class<Searcher> getObjectType() {
return Searcher.class;
}
....
}
工厂创建的类:
public class Searcher() {
private Service service;
@Autowired
public void setService(Service service) {
// never invoked
this.service=service;
}
}
答案 0 :(得分:29)
这是一个为您自动装配的抽象FactoryBean
实现:
public abstract class AbstractAutowiringFactoryBean<T> extends
AbstractFactoryBean<T> implements ApplicationContextAware{
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(
final ApplicationContext applicationContext){
this.applicationContext = applicationContext;
}
@Override
protected final T createInstance() throws Exception{
final T instance = doCreateInstance();
if(instance != null){
applicationContext
.getAutowireCapableBeanFactory()
.autowireBean(instance);
}
return instance;
}
/**
* Create the bean instance.
*
* @see #createInstance()
*/
protected abstract T doCreateInstance();
}
扩展它,实施getObjectType()
和doCreateInstance()
方法,然后启动并运行自动装配。
注意:未应用BeanPostProcessors,这需要额外的代码。
答案 1 :(得分:20)
由FactoryBean
创建的对象由管理,但不由Spring实例化或配置。使用FactoryBean
,您自己负责。所有注入和配置必须由FactoryBean
有一种替代方案可能更适合您 - 使用annotation-based config instead of XML-based config。这意味着您可以在Java中使用复杂的实例化逻辑,同时仍然在对象本身上使用@Autowired
之类的东西。
我倾向于为所有非平凡的Spring应用程序使用注释样式配置,它使许多事情变得更容易。
答案 2 :(得分:18)
这个怎么样?
<bean id="serviceFactory"
class="some.package.SearcherFactory" />
<bean id="service"
factory-bean="serviceFactory"
factory-method="getObject"/>
...然后只需注入bean'service'而不关心代码中的工厂
答案 3 :(得分:4)
手动方式是:
您还可以在工厂bean中注入ApplicationContext
(或通过实施ApplicationContextAware
获取),并执行ctx.getAutowireCapableBeanFactory().autowireBean(bean)
我承认他们都感到奇怪。
但事实上,如果逻辑很简单(只是实例化),请使用prototype
范围。
答案 4 :(得分:0)
FactoryBean是一个接口,您作为开发人员在编写工厂类时实现,并且您希望工厂类创建的对象由Spring作为bean管理,而另一方面BeanFactory表示Spring IoC容器,它包含托管bean并提供检索它们的权限。它是框架核心的一部分,它实现了控制容器反转的基本功能。
在大多数情况下,您不会发现自己直接使用或实现BeanFactory接口,除非您正在扩展框架的核心功能。当您拥有需要由Spring管理的Factories创建的对象时,您将实现FactoryBean。
用更简洁的话来说,BeanFactory表示Spring容器,而FactoryBean表示工厂类,其创建的对象被拾取并在容器中注册为bean。
public class Neighborhood
{
public IEnumerable<House> Houses { get; set; }
}
public class House
{
public Address Address { get; set; }
public IEnumerable<Room> Rooms { get; set; }
}
public class Room
{
public IEnumerable<Furniture> Furniture { get; set; }
}
答案 5 :(得分:-4)
不,FactoryBean
创建的bean也由spring管理。