2013-03-18 22 views
6

Ich verfolge diese tutorial in Bezug auf das Pooling von Objekten im Frühjahr. Ich habe den Anweisungen des Tutorials gefolgt, aber wenn ich meine Anwendung starte, wird immer eine neue Instanz des Objekts generiert. Ich erwarte, dass vorhandene Objekte wiederverwendet werden, da ich die Objekte zusammenfasse. Daher sollten keine neuen Instanzen erstellt werden. Wenn ich auf die Getter-Methode der Bean zugreife, wird erneut eine neue Instanz der Bean erstellt.Wie poole ich Objekte im Frühling?

Was hätte ich falsch machen können? Habe ich das Konzept des Poolings im Frühling missverstanden?

Unten ist mein Code:

Anwendungskontext: (. Dies ist nur der Körper meines Anwendungskontext)

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

</bean> 

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

Der Controller: (Dies ist nur der Körper meines Methode)

@RequestMapping("/hello") 
public ModelAndView helloWorld(HttpServletRequest request, HttpServletResponse response) 
{ 
    String message = "Hello World, Spring 3."; 
    try 
    { 
     System.out.println("Accessing Application Context"); 
     ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 

     System.out.println("Getting Bean"); 
     SimpleBean simpleBean = (SimpleBean) context.getBean("simpleBean"); 
     //A new SimpleBean... is printed here. 

     System.out.println("Displaying Hello World: " + simpleBean.getRandomNum()); 
     //After this line, A new SimpleBean... is printed again. I simply access the getter method. Why does it create a new instance of SimpleBean? 

     return new ModelAndView("hello", "message", message); 
    }catch(Exception e) 
    { 
     System.out.println("Error: " + e); 
     e.printStackTrace(); 
     return new ModelAndView("hello", "message", "Error! " + e.getMessage()); 
    } 
} 

Die Bohne ich Pooling:

package com.bean; 

import java.util.Random; 

public class SimpleBean 
{ 
    int randomNum; 
    String str; 

    SimpleBean() 
    { 
     Random randomGenerator = new Random(); 
     randomNum = randomGenerator.nextInt(100); 

     //I'm printing this line just to check if a instance of this bean is created. 
     System.out.println("#####################A new SimpleBean was born: " + randomNum); 

     str = "This is a string."; 
    } 

    public int getRandomNum() 
    { 
     return randomNum; 
    } 

    public void setRandomNum(int randomNum) 
    { 
     this.randomNum = randomNum; 
    } 

    public String getStr() 
    { 
     if (str == null) 
      return "str is null"; 
     return str; 
    } 

    public void setStr(String str) 
    { 
     this.str = str; 
    } 
} 

Der Körper meines web.xml:

<display-name>Spring3MVC</display-name> 

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/classes/applicationContext.xml</param-value> 
</context-param> 

<welcome-file-list> 
    <welcome-file>index.jsp</welcome-file> 
</welcome-file-list> 

<servlet> 
    <servlet-name>spring</servlet-name> 
    <servlet-class> 
     org.springframework.web.servlet.DispatcherServlet 
    </servlet-class> 
    <load-on-startup>1</load-on-startup> 
</servlet> 
<servlet-mapping> 
    <servlet-name>spring</servlet-name> 
    <url-pattern>*.html</url-pattern> 
</servlet-mapping> 
+1

Haben überprüfen Sie für mehr als 2 Wünsche? – Kishore

+0

Ja. Ich habe versucht, mehr als 2 Anfragen auszugeben, selbst die 'maxSize' meines Pools ist nur 2. Alle Anfragen, die ich gemacht habe, haben eine neue Instanz von' SimpleBean' erstellt, was ich nicht erwartet habe. Ich erwarte, dass vorherige Instanzen von SimpleBean wiederverwendet werden. – Arci

+0

Ich habe gerade den Spring-Source-Code von Bean Kontext überprüft. Ich finde den Code nicht heraus, in dem 'ClassPathXmlApplicationContext' das Singleton zwischenspeichert. aber ich weiß, dass diese Klasse 'SingletonBeanFactoryLocator' den Anwendungskontext durch factoryKey zwischenspeichert, ich wickle ihn ein und benutze ihn oft in meinem System. –

Antwort

9

Auf jeder Anfrage Sie einen brandneuer Spring-Anwendungskontext erstellen, erhalten Sie neues Objekt in einem neuen Kontext applicatin jede Aktion . Also sollten Sie Ihren Spring-Kontext laden, verwenden Sie 'ContextLoaderListener' in web.xml.

Referenz-Fragment in web.xml

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value> 
     classpath*:spring/appContext.xml classpath*:spring/appContext-security.xml 
    </param-value> 
</context-param> 

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

Sehen Sie den Code ein:

try 
{ 
    System.out.println("Accessing Application Context"); 
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 
    ... 

Für mehr Wissen über Kontext Laden Spring, siehe MKyong 's tutorial oder Spring reference

+0

Hallo, Henry! Danke, dass du das unterstrichen hast! Ich werde das überprüfen. Ich dachte, 'ClassPathXmlApplicationContext' würde mir nur einen neuen Verweis auf den' ApplicationContext' geben, keine neue Instanz von 'ApplicationContext'. – Arci

0

Wenn Sie es Sie erwähnen, bedeutet Ich sage dem Dienstanbieter von urs pooling, dass Sie maximal zwei Objekte mit Objektstatus erstellen möchten, die über urs co bereitgestellt werden nstruktor.

SimpleBean() 
    { 
     Random randomGenerator = new Random(); 
     randomNum = randomGenerator.nextInt(100); 

     //I'm printing this line just to check if a instance of this bean is created. 
     System.out.println("#####################A new SimpleBean was born: " + randomNum); 

     str = "This is a string."; 

    } 

so Simplebean Simplebean = (Simplebean) context.getBean ("Simplebean"); ist ein gepooltes Objekt. iF zwei Ausführungspfad möchte einen Service von simpleBean erhalten, dann wird diese Objektinstanz über Pooling bereitgestellt. Wenn mehr als zwei Ausführungspfade vorhanden sind, wird sie über den Prototypbereich bereitgestellt.

+0

Hallo. Danke für deine Antwort! Ja, ich verstehe, dass eine neue Instanz der Bean erstellt wird, wenn ich die Größe meines Pools überschritten habe. Ich stelle jedoch nur einzeln eine Anfrage. So ist es für mich unmöglich, die Anzahl meines Pools zu überschreiten. – Arci

+0

Verwenden Sie Thread-Pooling für den Dienst urs, wenn Sie die Poolgröße von urs überschreiten möchten. –

+0

Geben Sie scope = 'request' ein, wenn Sie mit http test arbeiten. Wenn nicht http, geben Sie scope = 'thread' ein, wenn Sie mehr als einen Ausführungspfad erstellen wollen. –

0

Versuchen Sie dies funktionieren wird ...

<property name="targetSource" ref="poolTargetSource" /> 

<!-- Added so that different instance of object is created --> 
<property name="singleton" value="false" />