【发布时间】:2014-11-02 10:14:59
【问题描述】:
我有一个应用程序,现在正在尝试使用Spring对其进行重构,使用new创建对象时遇到问题,但我不知道如何解决。
这里是关系:
我有一个Controller,需要一个CommandService 实例,而CommandService 需要一个RoomService 来创建AbstractRoom 实例以放入RoomService 实例的hashmap。
我有两种AbstractRoom,分别称为RoomA、RoomB,它们是从AbstractRoom扩展而来的,而AbstractRoom需要GameService实例。
我会将一个参数从 commandService 传递给 roomService,以便 roomservice 可以创建正确的房间实例。
现在的问题是,我使用 roomservice.createRoom 创建了一个使用new 的房间。所以 Spring 不能将 GameService 注入到我的 Abstract Room 中,因此我有一个 null gameService。
但是 CommandService 会从用户那里获得一些输入并委托给RoomService 为其创建一个房间,所以在用户输入之前我不知道会创建哪个房间实例:
CommandService.java:
private String handleCreateRoom(String userID, int playerCount,
Mode roomMode) {
...
AbstractRoom theNewRoom=roomService.createRoom(userID, playerCount, roomMode);
...
}
这是我从 RoomService.java 创建房间的方法:
public AbstractRoom createRoom(String userID,int playerCount,Mode roomMode){
AbstractRoom room = newRoom(roomMode);// create a room based on the roomMode
room.initRoom(userID, playerCount);// init the room
userToRoom.put(userID, room.getRoomNum());//some context
return room;
}
public AbstractRoom newRoom(AbstractRoom.Mode roomMode) {
Integer randomNumObject;
AbstractRoom newRoom;
.....
if(roomMode.equals(Mode.AUTO_JUDGE)||roomMode.equals(Mode.PLAYER_JUDGE)){//wodi room
newRoom=new RoomA(randomNumObject,roomMode);//RoomA
}
....
else{//RoomB
newRoom=new RoomB(randomNumObject);
}
roomMap.put(randomNumObject, newRoom);//some context
return newRoom;
}
这是我的 AbstractRoom.java
public abstract class AbstractRoom {
protected Mode roomMode;
@Autowired
protected GameService gameService;
.....
}
而我的配置是:
@Configuration
@EnableAspectJAutoProxy
public class Application {
@Bean
public CommandService commandService(){
return new CommandService();//singleton
}
@Bean
public RoomService roomService(){
return new RoomService();//singleton
}
@Bean
public GameService gameService(){
return new GameService();//singleton
}
【问题讨论】:
-
我不会让 Room 依赖于服务。那看起来不对。如果你真的需要,那么在房间构造函数中显式传递服务,或者将 Room 设置为原型 bean 并使用 Spring 应用程序上下文来获取实例。
-
"将 Room 设为原型 bean,并使用 Spring 应用程序上下文获取实例。"我想这就是我现在想要的,但我是 Spring 的新手,你能告诉我如何在答案中做到这一点吗?谢谢!
-
@JBNizet,谢谢!现在我使用 new AnnotationConfigApplicationContext(Application.class).getBean(RoomService.class),在声明 AbstratRoom 的 bean 时,但是我还有一个问题,我的服务现在不是单例了! stackoverflow.com/questions/26698962/…
-
您只创建一次应用程序上下文。在你需要的地方自动装配,就像我链接到的答案一样。
标签: java spring dependency-injection refactoring inversion-of-control