簡體   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