如何让FactoryBean创建的bean被spring管理?
FactoryBean 可用于以编程方式创建可能需要复杂实例化逻辑的对象。
然而,由 FactoryBean
创建的 Bean 似乎并未由 Spring 管理。这个解释正确吗?如果是这样,有什么好的解决方法吗?包含一个简短的代码示例来说明我的问题。
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;
}
}
The FactoryBean can be used to programmatically create objects which might require complex instantiation logic.
However, it seems that the beans created by the FactoryBean
doesn't become spring managed. Is this interpretation correct? If so, are there any nice workarounds? A short code sample is included to illustrate my problem.
ApplicationContext:
<bean id="searcher" class="some.package.SearcherFactory" />
<bean id="service" class="some.package.Service" />
Factory implementation:
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;
}
....
}
Class created by the factory:
public class Searcher() {
private Service service;
@Autowired
public void setService(Service service) {
// never invoked
this.service=service;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这是一个抽象的
FactoryBean
实现,可以为您进行自动装配:扩展它,实现
getObjectType()
和doCreateInstance()
方法,然后您就可以了通过自动装配启动并运行。注意: 未应用 BeanPostProcessors,这需要额外的代码。
Here is an abstract
FactoryBean
implementation that does autowiring for you:Extend it, implement the
getObjectType()
anddoCreateInstance()
methods and you're up and running with autowiring.Note: BeanPostProcessors are not applied, that would require additional code.
FactoryBean
创建的对象由 Spring 管理,但不由 Spring 实例化或配置。通过使用FactoryBean
,您自己对此负责。所有注入和配置都必须由FactoryBean
处理有一种替代方案可能更适合您 - 使用 基于注释的配置而不是基于 XML 的配置。这意味着您可以在 Java 中拥有复杂的实例化逻辑,同时仍然在对象本身上使用诸如
@Autowired
之类的东西。我现在倾向于对所有重要的 Spring 应用程序使用注释式配置,它使许多事情变得更加容易。
The object created by the
FactoryBean
are managed by Spring, but not instantiated or configured by Spring. By using aFactoryBean
, you take responsibility for that yourself. All injection and config must be handled by theFactoryBean
There is an alternative which may work better for you - use annotation-based config instead of XML-based config. This means you can have complex instantiation logic in Java, whilst still using things like
@Autowired
on the objects themselves.I tend to use annotation-style config for all non-trivial Spring apps now, it makes many things a lot easier.
这又如何呢?
...然后只需注入 bean 'service' 并且不关心代码中的工厂
What about this ?
... and then just inject the bean 'service' and do not care about the factory in your code
手动方法是:
您还可以在工厂 bean 中注入
ApplicationContext
(或通过实现ApplicationContextAware
获取它),并执行ctx.getAutowireCapableBeanFactory().autowireBean(bean)
不过我承认两者都感觉很奇怪。
但事实上,如果逻辑那么简单(仅实例化),请使用原型范围。
A manual way would be:
You can also inject
ApplicationContext
in the factory bean (or get it by implementingApplicationContextAware
), and doctx.getAutowireCapableBeanFactory().autowireBean(bean)
I admit both feel strange, though.
But in fact, if the logic is that simple (only instantiation), use
prototype
scope.FactoryBean 是您作为开发人员在编写工厂类时实现的接口,并且您希望工厂类创建的对象由 Spring 作为 bean 进行管理,而 BeanFactory 则代表 Spring IoC 容器,它包含托管 bean 并提供检索它们的访问权限。它是框架核心的一部分,实现控制反转容器的基本功能。
在大多数情况下,您不会发现自己直接使用或实现 BeanFactory 接口,除非您要扩展框架的核心功能。当您有由工厂创建的对象需要由 Spring 管理时,您会实现 FactoryBean。
更简洁地说,BeanFactory 代表 Spring 容器,而 FactoryBean 代表工厂类,其创建的对象被拾取并注册为容器中的 bean。
A FactoryBean is an interface that you, as a developer, implements when writing factory classes and you want the object created by the factory class to be managed as a bean by Spring, while a BeanFactory on the other hand, represents the Spring IoC container, it contains the managed beans and provides access to retrieving them. It is part of the core of the framework which implements the base functionality of an inversion of control container.
In most cases you won't find yourself using or implementing the BeanFactory interface directly, unless you are extending the core functionality of the framework. While you would do implement the FactoryBean when you have objects that are created by Factories that needs to be managed by Spring.
In more succinct words, the BeanFactory represents the Spring container while the FactoryBean represents factory classes whose created object are picked up and registered as a bean in the container.