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

Java web应用程序中的Spring SimpleThreadScope:容器池的一部分?,java,spring,web-applications,Java,Spring,Web Applications,拥有公开加密功能的服务。我们不需要清理,也不希望每次/每次会话都创建对象。但我需要一个单独的对象每个线程 在web应用程序中-作用域是web容器的线程池吗 在Spring3和Spring4实现中是一样的吗 我们计划使用它的另一个地方是缓存SimpleDataFormat对象。同样,我们不需要清理方法。在spring框架中,为了每个线程获得一个单独的对象,我们可以通过将bean范围作为原型来实现这一点 从 与此具体案例相关的&4没有变化。关于对象清理,原型范围的行为与同一参考文件不同 与其他作

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

在web应用程序中-作用域是web容器的线程池吗

在Spring3和Spring4实现中是一样的吗


我们计划使用它的另一个地方是缓存SimpleDataFormat对象。同样,我们不需要清理方法。

在spring框架中,为了每个线程获得一个单独的对象,我们可以通过将bean范围作为原型来实现这一点


与此具体案例相关的&4没有变化。关于对象清理,原型范围的行为与同一参考文件不同

与其他作用域不同,Spring并不管理原型bean的整个生命周期:容器实例化、配置和以其他方式组装原型对象,并将其交给客户机,而没有该原型实例的进一步记录。因此,尽管对所有对象调用初始化生命周期回调方法,而不考虑范围,但对于原型,不会调用配置的销毁生命周期回调。客户机代码必须清理原型范围的对象,并释放原型bean所持有的昂贵资源


在spring框架中,为了每个线程获得一个单独的对象,我们可以通过将bean范围作为原型来实现这一点


与此具体案例相关的&4没有变化。关于对象清理,原型范围的行为与同一参考文件不同

与其他作用域不同,Spring并不管理原型bean的整个生命周期:容器实例化、配置和以其他方式组装原型对象,并将其交给客户机,而没有该原型实例的进一步记录。因此,尽管对所有对象调用初始化生命周期回调方法,而不考虑范围,但对于原型,不会调用配置的销毁生命周期回调。客户机代码必须清理原型范围的对象,并释放原型bean所持有的昂贵资源

为您提供的解决方案:

  • 提供您自己的FactoryBean来创建您的服务bean
  • 在FactoryBean中,应该使用ThreadLocal保存bean,如果不存在,则创建一个并将其保存到ThreadLocal,下次从ThreadLocal检索它 为您提供的解决方案:

  • 提供您自己的FactoryBean来创建您的服务bean
  • 在FactoryBean中,应该使用ThreadLocal保存bean,如果不存在,则创建一个并将其保存到ThreadLocal,下次从ThreadLocal检索它 具有线程范围的对象。 其次,数据格式通常不同步。所以要注意线程问题。 顺便问一下,当你说“每个线程”时,你是指每个请求吗?如上所述,在web环境中使用RequestScope通常更可取

    可以用类似的原型创建豆类,请求,你可能要考虑。正如@Sairam所提到的,生命周期管理也值得考虑。

    有线程范围的对象。 其次,数据格式通常不同步。所以要注意线程问题。 顺便问一下,当你说“每个线程”时,你是指每个请求吗?如上所述,在web环境中使用RequestScope通常更可取


    可以用类似的原型创建豆类,请求,你可能要考虑。正如@Sairam所提到的,生命周期管理也值得考虑。

    自3.0版以来,Spring就有了线程作用域的基本概念:
    SimpleThreadScope
    。看起来它可以满足你的要求,但它有一些局限性:

    • 默认情况下,它不在容器中注册,但必须明确注册
    • 它不会对其bean执行清理
    如果您能够适应这些限制,您可以通过编程方式注册范围:

    Scope threadScope = new SimpleThreadScope();
    appContext.getBeanFactory().registerScope("thread", threadScope);
    
    或在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>
    

    该示例使用
    ProxyFactoryBean
    提供一个aop代理,允许在单例bean中注入
    simpleBean
    ,前提是将其作为接口注入。

    自3.0版以来,Spring有一个线程作用域的基本概念:
    SimpleThreadScope
    。看起来它可以满足你的要求,但它有一些局限性:

    • 默认情况下,它不在容器中注册,但必须明确注册
    • 它不会对其bean执行清理
    如果您能够适应这些限制,您可以通过编程方式注册范围:

    Scope threadScope = new SimpleThreadScope();
    appContext.getBeanFactory().registerScope("thread", threadScope);
    
    或在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>
    

    该示例使用
    ProxyFactoryBean
    提供一个aop代理,允许在单例bean中注入
    simpleBean
    ,前提是将其作为接口注入。

    您为此尝试过拦截器吗?您为此尝试过拦截器吗?是的,这就是我想听到的。我们正在使用它,只是很惊讶很少有其他人在使用它。你积极地使用这个吗?您是否评估服务以查看它们是否可以是线程级bean,并且在运行时实例化的bean更少,重用的bean更多?没有,但我曾经使用过Unbounded LDAP SDK for Java,它们有不同的内存池用于保存LDAP连接,包括为每个线程维护专用连接的内存池。文档中指出,这种实现不需要确定如何最好地调整连接池的大小,并且在尝试访问一组共享的连接时,它可以消除线程之间的争用,但其余部分清楚地表明,非线程支持的实现是首选的实现。据我所知,线程实现只是因为在非prod环境中易于配置而存在。感谢您将您的答案标记为“现在”,将在一两天内给予赏金
    <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>