【问题标题】:Spring scope usage for instance variables实例变量的 Spring 范围使用
【发布时间】:2016-06-02 15:16:40
【问题描述】:

我们正在实现 Spring 服务,@Webservice 层是单例的,它调用一个原型“服务”层。 Service 层有很多实例变量,因此认为将其作为原型是理想的,但是,由于 @Webservice 层是单例的,因此看起来该原型只实例化了一次。

哪种类型的@Scope 适合我们?我们在服务层上有很多实例变量,我们很难将它们设置为方法的本地变量,因为很多代码因此需要更改。

如果我将所有层都设为单例,两个线程是否共享实例变量?

【问题讨论】:

  • 一个作用域代理原型。
  • @SotiriosDelimanolis 你能详细说明一下吗?
  • @SotiriosDelimanolis 在注释中是否有等效项?
  • 是的,@org.springframework.context.annotation.Scope

标签: java spring web-services spring-mvc


【解决方案1】:

给定一个带有注入目标的单例 bean,Spring 将初始化 bean 并立即注入字段/方法/构造函数。如果该注入目标是一个原型 bean,那么 Spring 将只执行一次。

大概,您希望在单例处理的每个操作或事件上都有一个新的原型 bean。您将需要一个 AOP 范围的代理。这在 Scoped proxies and dependencies 的 Spring 章节中有记录。使用已配置的作用域代理,Spring 将注入一个代理而不是原型 bean。

代理本身会将对其的所有调用委托给一个原型 bean,每次都是一个新实例。

通过注解配置,您可以配置@Bean@Component

@Scope(scopeName = BeanDefinition.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)

这告诉 Spring 为 bean 配置一个代理,该代理将继承目标的实际类类型并成为原型。

当你然后注入它时

@Autowired
private MyPrototypeBean bean;

bean 将持有对代理对象的引用。然后你可以调用方法

bean.method();

这将委托给一个新实例。这意味着每次调用

bean.method();
bean.method();
bean.method();

将操作一个新实例,在上面的例子中三个新实例。如果您只希望一个实例调用这些方法,您可以从代理中提取它。查看提供的解决方案here

MyPrototypeBean target = null;
if (AopUtils.isJdkDynamicProxy(proxy)) {
    target = (MyPrototypeBean) ((Advised)proxy).getTargetSource().getTarget();
} // won't work for CGLIB classes AFAIK (gotta search)

【讨论】:

    猜你喜欢
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 2013-10-01
    • 2014-08-12
    • 1970-01-01
    • 2014-04-18
    • 2015-11-15
    • 2011-08-09
    相关资源
    最近更新 更多