java 如何在 Spring 中池对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15472935/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to pool objects in Spring?
提问by Arci
I'm following this tutorialregarding how to pool objects in Spring. I've followed the instruction written on the tutorial but when I run my application, it always generates a new instance of the object. I'm expecting that since I'm pooling the objects, existing objects will be reuse. As such, no new instances should be created. Also, when I access of the getter method of the bean, a new instance of the bean is created again.
我正在关注有关如何在 Spring 中池化对象的教程。我已经按照教程中的说明进行操作,但是当我运行我的应用程序时,它总是会生成一个新的对象实例。我期望因为我正在汇集对象,所以现有的对象将被重用。因此,不应创建新实例。此外,当我访问 bean 的 getter 方法时,将再次创建 bean 的一个新实例。
What could have I done wrong? Did I misunderstood the concept of pooling in Spring?
我可能做错了什么?我是否误解了 Spring 中池化的概念?
Below is my code:
下面是我的代码:
Application Context:(This is just the body of my application context.)
应用程序上下文:(这只是我的应用程序上下文的主体。)
<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>
The controller:(This is just the body of my method)
控制器:(这只是我方法的主体)
@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());
}
}
The bean I'm 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;
}
}
The body of my web.xml:
我的 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>
回答by Henry Leu
On each request, you create a brand new Spring application context, then you get new object in a new applicatin context each action. so you should load your spring context use 'ContextLoaderListener' in web.xml.
对于每个请求,您创建一个全新的 Spring 应用程序上下文,然后在每个操作的新应用程序上下文中获得新对象。所以你应该在 web.xml 中使用“ContextLoaderListener”加载你的 spring 上下文。
Reference fragment in 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>
See you code:
代码见:
try
{
System.out.println("Accessing Application Context");
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
...
For more knowledge about Spring context loading, see MKyong 's tutorialor Spring reference
有关 Spring 上下文加载的更多知识,请参阅Mkyong 的教程或Spring 参考
回答by abishkar bhattarai
When you mention it means you are saying to service provider of urs pooling that you want to create maximum of two objects with object state provided via urs constructor.
当您提到它时,这意味着您对 urs 池的服务提供者说您要创建最多两个对象,并通过 urs 构造函数提供对象状态。
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"); is a pooled object. iF two execution path want to get service from simpleBean then that object instance is provided via Pooling.If more thean two execution path then it is provided via prototype scope.
所以 SimpleBean simpleBean = (SimpleBean) context.getBean("simpleBean"); 是一个池化对象。如果两个执行路径想要从 simpleBean 获取服务,那么该对象实例通过池化提供。如果超过两个执行路径,那么它通过原型范围提供。
回答by Ashika
Try this will work...
试试这个会奏效...
<property name="targetSource" ref="poolTargetSource" />
<!-- Added so that different instance of object is created -->
<property name="singleton" value="false" />