2013-03-18 7 views
6

Я следую за этим tutorial относительно того, как объединить объекты весной. Я выполнил инструкцию, написанную в учебнике, но когда я запускаю свое приложение, он всегда генерирует новый экземпляр объекта. Я ожидаю, что, поскольку я объединяю объекты, существующие объекты будут повторно использоваться. Таким образом, новые экземпляры не должны создаваться. Кроме того, когда я получаю доступ к методу getter компонента, новый экземпляр компонента снова создается.Как объединить объекты весной?

Что я мог сделать неправильно? Не поняла ли я концепцию объединения весной?

Ниже мой код:

Применение Контекст: (. Это только тело моего контекста приложения)

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

Контроллер: (Это только тело мое метод)

@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()); 
    } 
} 

боба Я объединив:

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

Тело моей 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

Вы проверили более 2-х запросов? – Kishore

+0

Да. Я попытался выпустить более двух запросов, даже «maxSize» моего пула - всего 2. Все сделанные мной запросы создали новый экземпляр «SimpleBean», который я не ожидал. Я ожидаю, что предыдущие экземпляры SimpleBean будут использоваться повторно. – Arci

+0

Я только что рассмотрел исходный исходный код источника bean-компонента. Я не обнаружил код, в котором кеш «ClassPathXmlApplicationContext» одинарный. но я знаю, что этот класс «SingletonBeanFactoryLocator» использует контекст приложения кэша factoryKey, я обертываю его и часто его использую в своей системе. –

ответ

9

На каждом запросе, необходимо создать контекст совершенно новое приложение Spring, то вы получите новый объект в новом контексте Applicatin каждое действие , поэтому вы должны загрузить свой контекст контекста, используя «ContextLoaderListener» в web.xml.

Ссылка фрагмент в 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> 

Увидимся код:

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

Для получения дополнительных знаний о Spring контекста загрузки, см MKyong 's tutorial или Spring reference

+0

Привет, Генри! Спасибо что подметил это! Я проверю это. Я думал, что «ClassPathXmlApplicationContext» только даст мне новую ссылку на «ApplicationContext», а не на новый экземпляр «ApplicationContext». – Arci

0

При упоминании это означает, что вы говорят поставщику услуг о пуле urs, что вы хотите создать максимум два объекта с состоянием объекта, предоставленным через urs co nstructor.

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."; 

    } 

так SimpleBean SimpleBean = (SimpleBean) context.getBean ("SimpleBean"); является объединенным объектом. iF два пути выполнения хотят получить сервис от simpleBean, тогда этот экземпляр объекта предоставляется через пул. Если больше двух путей выполнения, то он предоставляется через область прототипа.

+0

Привет. Спасибо за ваш ответ! Да, я понимаю, что новый экземпляр компонента будет создан, если я превышу размер моего пула. Тем не менее, я только делаю запрос по одному за раз. Поэтому для меня невозможно превысить количество моего пула. – Arci

+0

Используйте пул потоков для обслуживания urs, если вы хотите превысить размер пула urs. –

+0

укажите scope = 'request', если вы работаете в http test.If non http, затем дайте scope = 'thread', если вы хотите создать несколько путей выполнения. –

0

Попробуйте это будет работать ...

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

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

Смежные вопросы