繁体   English   中英

如何使用Pooled Spring bean而不是Singleton?

[英]How to use Pooled Spring beans instead of Singleton ones?

出于效率原因,我有兴趣限制同时使用Spring应用程序上下文Bean的线程数(我不希望在有限的内存中处理无限数量的线程)。

我在这里 (春季文档)找到了一种通过执行以下操作以EJB样式合并bean来实现此目的的方法:

  • 将目标bean声明为作用域“原型”。
  • 声明一个池提供程序,它将提供有限数量的池“目标”实例。
  • 声明一个“ ProxyFactoryBean”,该功能我不清楚。

这是此bean的声明:

<bean id="businessObjectTarget" class="com.mycompany.MyBusinessObject" 
    scope="prototype">
  ... properties omitted
</bean>

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

<bean id="businessObject" class="org.springframework.aop.framework.ProxyFactoryBean">
  <property name="targetSource" ref="poolTargetSource"/>
  <property name="interceptorNames" value="myInterceptor"/>
</bean>

我的问题是,当我声明另一个bean使用“ businessObjectTarget”的池化实例时,应该怎么做? 我的意思是,当我尝试执行以下操作时:

<bean id="clientBean" class="com.mycompany.ClientOfTheBusinessObject">
  <property name="businessObject" ref="WHAT TO PUT HERE???"/>
</bean>

“ ref”的值应该是多少?

您不能使用属性来获取原型的实例。
一种选择是使用查找方法(请参阅第3.3.7.1章 )。
在代码中获取bean的另一种选择:使com.mycompany.ClientOfTheBusinessObject实施ApplicationContextAware接口,然后调用context.getBean("clientBean")

我使用Java配置在接口上构造了一个代理,该接口使用apache commons-pool处理池以实现调用级池。

请注意春季示例中的第三个bean的名称:-“ businessObject”

这意味着您应该从那里访问公共池的bean。

对于您的情况,如果您需要自己的客户Bean,则可以按如下所示进行操作。 但是在这种情况下,不需要businessObject。

<bean id="businessObjectTarget" class="com.mycompany.MyBusinessObject" 
    scope="prototype">

  ... properties omitted
</bean>

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

<bean id="clientBean" class="com.mycompany.ClientOfTheBusinessObject">
 <property name="poolTargetSource" ref="poolTargetSource"/>
</bean>


Java classes:-
public class ClientOfTheBusinessObject{
     CommonsPoolTargetSource poolTargetSource;
//<getter and setter for poolTargeTSource>
  public void methodToAccessCommonPool(){
     //The following line gets the object from the pool.If there is nothing left in the pool then the thread will be blocked.(The blocking can be replaced with an exception by changing the properties of the CommonsPoolTargetSource bean)
     MyBusinessObject mbo = (MyBusinessObject)poolTargetSource.getTarget();
     //Do whatever you want to do with mbo
     //the following line puts the object back to the pool
     poolTargetSource.releaseTarget(mbo);
  }
}

我敢肯定,您可以用较少复杂的方式限制并发线程的数量。 您是否看过Java并发API,特别是在Executors.newFixedThreadPool()上?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM