Web 应用程序中的 Spring SimpleThreadScope:容器池的一部分?

tgk*_*rog 1 java spring web-applications

拥有一项公开加密功能的服务。我们不需要清理,也不希望每次/每次会话都创建对象。但我需要每个线程一个单独的对象。

在 Web 应用程序中 - 范围是 Web 容器的线程池吗?

spring 3 和 spring 4 的实现是一样的吗?

我们计划使用它的另一个地方是缓存 SimpleDateFormat 对象。再次不需要清理方法。

Ser*_*sta 5

从 3.0 版本开始,Spring 有了线程作用域的基本概念:SimpleThreadScope. 看起来它可以满足您的要求,但它有一些限制:

  • 默认情况下,它没有在容器中注册,但必须明确注册
  • 它不对其 bean 执行任何清理。

如果您可以适应这些限制,则可以以编程方式注册范围:

Scope threadScope = new SimpleThreadScope();
appContext.getBeanFactory().registerScope("thread", threadScope);
Run Code Online (Sandbox Code Playgroud)

或在 xml 配置中:

<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
    <property name="scopes">
        <map>
            <entry key="thread">
                <bean class="org.springframework.context.support.SimpleThreadScope"/>
            </entry>
        </map>
    </property>
</bean>
Run Code Online (Sandbox Code Playgroud)

这在 Spring 3 和 Spring 4 中的工作原理相同。如果您想在单例 bean 中注入一个线程作用域 bean,您必须在其上声明一个 aop 作用域代理:

<bean id="bar" class="x.y.Bar" scope="thread">
    <property name="name" value="Rick"/>
    <aop:scoped-proxy/>
</bean>
<bean id="foo" class="x.y.Foo">
    <property name="bar" ref="bar"/>
</bean>
Run Code Online (Sandbox Code Playgroud)

(来自 Spring Framework 参考文档的所有示例)。

如果您必须进行一些清理,您可以查看此文档Spring by Example Custom Thread Scope Module,其中显示了SimpleThreadScope.

但我不确定你真的想要那个,除非所有线程都持续使用线程范围的 bean,否则内存不是真正的问题。因为在这种设计模式中,如果一次只有一个会话需要 bean,但它由多个线程提供服务(假设其他请求不需要 bean),那么所有线程都将获得 bean 的不同实例,而使用池中只会使用一个实例。

您将CommonsPoolTargetSource在 SO如何在 Spring 中池化对象?. 从帖子中摘录:

<bean id="simpleBeanTarget" class="com.bean.SimpleBean" scope="prototype"/>

<bean id="poolTargetSource" class="org.springframework.aop.target.CommonsPoolTargetSource">
    <property name="targetBeanName" value="simpleBeanTarget" />
    <property name="maxSize" value="2" />
</bean>

<bean id="simpleBean" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="targetSource" ref="poolTargetSource" />
</bean>
Run Code Online (Sandbox Code Playgroud)

该示例使用 aProxyFactoryBean来提供 aop 代理以允许simpleBean在单例 bean 中注入,前提是它作为接口注入。