【发布时间】:2012-03-28 07:33:29
【问题描述】:
正如上面的标题,我对直接@Autowired注解注入applicationContext或在单例spring bean中实现ApplicationContextAware接口之间的利弊感到困惑。
在哪些情况下您更喜欢哪一种,为什么?谢谢。
【问题讨论】:
标签: spring dependency-injection spring-3 applicationcontext
正如上面的标题,我对直接@Autowired注解注入applicationContext或在单例spring bean中实现ApplicationContextAware接口之间的利弊感到困惑。
在哪些情况下您更喜欢哪一种,为什么?谢谢。
【问题讨论】:
标签: spring dependency-injection spring-3 applicationcontext
实际上,两者都不好。它们都将您的应用程序绑定到 Spring 框架,从而颠倒了整个控制反转的概念。在理想情况下,您的应用程序根本不应该意识到由 ApplicationContext 管理。
一旦你选择了违反这个原则,你怎么做都没有关系。 ApplicationContextAware 是 at least since Version 2.0 周围的旧版本。 @Autowired 是一种较新的机制,但它们的工作方式几乎相同。我可能会选择ApplicationContextAware,因为它在语义上清楚地表明了它的含义。
【讨论】:
正如@Sean Patrick Floyd 所说,对 ApplicationContext 的需求通常是由于糟糕的设计。但有时你别无选择。在这些情况下,我更喜欢使用@Autowired,因为这是我注入所有其他属性的方式。那么,如果我使用 @Autowired 来注入 MyRepository,为什么我不能将它用于 ApplicationContext 或任何其他 Spring bean?
我只将 Spring 接口用于那些我不能用注解做的事情,例如 BeanNameAware。
【讨论】:
如果您需要在单例中获取原型,则可以使用方法注入。基本上,您创建一个返回所需对象的抽象方法,并且每次调用该方法时,spring 都会返回原型。您在 spring 配置中定义“查找方法”。以下是一些链接: http://docs.spring.io/spring/docs/1.2.9/reference/beans.html#beans-factory-method-injection http://java.dzone.com/articles/method-injection-spring
【讨论】:
由于您没有扩展任何 spring 类,因此您的应用程序始终与框架分离。大多数情况下,您不想注入ApplicationContext,而是需要注入ApplicationContext 中定义的bean。
最好的情况是始终坚持最低限度,除非您有任何特定要求,这对于 spring 非常简单。
要么,
在application context 中注释您的bean 和scan,然后使用@Autowire 将它们连接起来。
使用application context 连接您的 bean 权宜之计(旧的 xml 样式配置)。您也可以通过这种方法使用@Autowire。
当您想控制 bean 生命周期时,您可以读取 API 并对其进行自定义,但大多数情况下这些常规设置可以完成工作。
这里有一些例子。
【讨论】:
根本不需要使用ApplicationContext。
如果您需要在单例 bean 中使用原型作用域 bean,请注入 org.springframework.beans.factory.ObjectFactory。
例如使用构造函数注入:
@Service
class MyClass {
private ObjectFactory<MyDependency> myDependencyFactory;
public MyClass(ObjectFactory<MyDependency> prototypeFactory) {
myDependencyFactory = prototypeFactory;
}
}
现在使用 ApplicationContext 有什么好处?
您可以通过简单地传递一个返回其存根版本的 lambda(因为 ObjectFactory 是一个 @FunctionalInterface)来替换此依赖项(例如在测试中)。
虽然可以对 ApplicationContext 进行存根,但在这种情况下尚不清楚哪些 bean 将被查找并需要存根。
【讨论】: