【发布时间】:2018-04-27 07:23:07
【问题描述】:
我对使用方法注入(lookup-method)和aop scoped-proxy(因为两者都用于不同范围的bean注入)有点困惑,所以
1) 何时使用方法注入以及何时使用 aop-scoped proxy ? 2) 原型 bean 不使用 aop-scoped proxy 的原因是什么?
【问题讨论】:
标签: spring spring-mvc spring-boot
我对使用方法注入(lookup-method)和aop scoped-proxy(因为两者都用于不同范围的bean注入)有点困惑,所以
1) 何时使用方法注入以及何时使用 aop-scoped proxy ? 2) 原型 bean 不使用 aop-scoped proxy 的原因是什么?
【问题讨论】:
标签: spring spring-mvc spring-boot
查找方法注入和作用域代理都是将寿命较短的 bean 注入寿命较长的 bean 的方法。但是,它们服务于不同的用例。
方法注入在单例范围的 bean 依赖于原型范围的 bean 的情况下很有用。
一个代理被注入来代替所需的 bean,并根据上下文提供该 bean。例如,如果一个单例 bean(例如 Spring MVC 控制器)自动连接一个会话范围的 bean,那么代理会交付属于当前 HTTP 会话的那个 bean。
这样的代理不适用于在运行时获取原型 bean 的情况。查找方法注入是在运行时获取原型实例的一种方式。
但是,方法注入有局限性,因为它建立在抽象方法之上。因此,编写单元测试之类的某些事情更加麻烦,因为您需要提供抽象方法的存根实现。组件扫描也不适用于抽象类。
方法注入的一种替代方法是 Spring 的 ObjectFactory,或其 JSR 等效的 Provider。
另一种在运行时创建原型 bean 实例的直接方法(甚至可以提供构造函数参数)是实现如下所示的 bean 工厂:
@Configuration
public class MyProvider {
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public MyThing create(String name) {
return new MyThing(name);
}
}
用法:
@Component
public class MySingleton {
@Autowired
private MyProvider myProvider;
public void doStuffThatNeedsAPrototypeBeanInstance() {
MyThing thing = myProvider.create("some name");
...
}
}
【讨论】:
对于问题1.什么时候使用方法注入,什么时候使用aop-scoped proxy?
假设你有一个单例 bean A 依赖于原型 bean B。A 有一个方法 m 涉及到 B。
你得到了 A 的对象 a 并多次执行方法 m。每次 m 执行时,B 的一个新对象 b 需要注入到 a。那就是你使用方法注入的时候了。
此外,如果你有一个单例 bean,A 依赖于会话 bean B。A 有一个方法 m,其中涉及 B。
你得到了 A 的对象 a 并多次执行方法 m。只要执行时间在同一个会话中,a就拥有B的同一个对象b。那就是你使用代理的时间。
【讨论】: