【发布时间】:2014-12-29 04:58:34
【问题描述】:
我有一个问题,我有一个 ClassA 需要注入 RoomService,我在 ClassA 中发现它工作正常,roomService 的 id 是相同的。
虽然出于某种原因,我需要 roomservice 根据一些输入参数为我创建房间实例,所以我使用下面的配置来实现这一点:
@Configuration
@EnableAspectJAutoProxy
public class Application {
private static ApplicationContext ctx = new AnnotationConfigApplicationContext(Application.class);
public static ApplicationContext getApplicationContext(){
return ctx;
}
@Bean
public RoomService roomService(){
return new RoomService();//Singleton
}
@Bean
@Scope("prototype")
public AbstractRoom room(AbstractRoom.Mode roomMode){
RoomService roomService = (RoomService) ctx.getBean(RoomService.class);
LogUtil.debug("--------from application:" +roomService.id1);//here, I find the id is different every time
return roomService.newRoom(roomMode);
}
}
问题是我需要 RoomService 是单例的,但我发现在 Application.java 中, ctx.getBean(roomService) 总是返回一个具有不同 id 的不同 bean。 Spring不应该重用同一个bean吗?这是为什么呢?
这是我在 RoomService.java 中创建房间的方法
public AbstractRoom createRoom(String userID,int playerCount,Mode roomMode){
ApplicationContext ctx =Application.getApplicationContext();
AbstractRoom room = (AbstractRoom)ctx.getBean(AbstractRoom.class,roomMode);
}
更新:
我尝试重用相同的 ctx,但它不起作用。一个提示是,当我运行 tomcat 启动它时,我发现我的 RoomService() 的构造函数被多次调用(我在其中设置了一个断点。)
这是我的 web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>wodinow</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
请帮忙!
【问题讨论】:
-
每次从应用程序上下文中获取 RoomService 时,它可能会有所不同,因为每次调用 room() 时都会创建并关闭应用程序上下文。我认为 RoomService 保证在单个应用程序上下文实例中是单例的。
-
@BohuslavBurghardt,我试过不调用 ctx.close(),一样。我想我得到了不同的上下文,因为我使用
new来获取上下文。
标签: java spring inversion-of-control ioc-container spring-ioc