0

我有一個應用程序,現在我想用Spring來重構它,並且在使用new創建對象時遇到問題,但我不知道如何解決它。Spring使用new創建對象時注入的bean null,如何解決它?

這裏是realtionship:

我有一個Controller,需要一個CommandService實例和CommandService需要RoomService創建AbstractRoom實例投入RoomService實例的HashMap中。

我有兩種AbstractRoom叫羅馬,RoomB,他們從AbstractRoom延伸,並AbstractRoom需求GameService實例。

我會將一個參數從commandService傳遞給roomService,以便roomservice可以創建一個正確的房間實例。

現在的問題是,我使用roomservice.createRoom創建一個房間,使用new來做到這一點。所以Spring不能將GameService注入到我的抽象空間,因此我有一個null gameService。

但CommandService會得到用戶和委託給RoomService爲它創建一個房間的一些投入,所以我不知道哪個房間實例將直至用戶輸入的東西創建:

CommandService.java:

private String handleCreateRoom(String userID, int playerCount, 
     Mode roomMode) { 
     ... 
     AbstractRoom theNewRoom=roomService.createRoom(userID, playerCount, roomMode); 
     ...   
     } 

下面是我從RoomService.java如何createRoom:

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 
    } 
+0

我不會讓房間依賴於服務。這看起來不對。如果你真的需要這個,那麼在房間構造函數中明確地傳遞這個服務,或者讓Room成爲一個原型bean,然後使用Spring應用程序上下文來獲得一個實例。 – 2014-11-02 10:20:48

+0

「使Room成爲原型bean並使用Spring應用程序上下文獲取實例。」我想這是我現在想要的,但我對春天來說是新的,請你告訴我如何在答案中做到這一點?謝謝! – Jaskey 2014-11-02 10:24:26

+0

http://stackoverflow.com/questions/22155832/spring-java-config-how-do-you-create-a-prototype-scoped-bean-with-runtime-argu – 2014-11-02 10:31:43

回答

0

最後,我解決了這個問題,讓AbstractRoom與範圍=原型的bean,並從房間服務豆返回實例。

@Configuration 
@EnableAspectJAutoProxy 
public class Application {  
    @Bean 
    public CommandService commandService(){ 
     return new CommandService(); 
    } 

    @Bean 
    public RoomService roomService(){ 
     return new RoomService(); 
    } 

    @Bean 
    public GameService gameService(){ 
     return new GameService(); 
    } 

    @Bean 
    @Scope("prototype") 
    public AbstractRoom room(AbstractRoom.Mode roomMode){ 
     RoomService roomService = roomService(); 
     return roomService.newRoom(roomMode); 
    } 

而且在RoomService.java,注入的ApplicationContext,並且從容器中得到房。

public class RoomService { 

    @Autowired 
    private ApplicationContext ctx; 

    public AbstractRoom createRoom(String userID,int playerCount,Mode roomMode){ 
     AbstractRoom room = (AbstractRoom)ctx.getBean(AbstractRoom.class,roomMode); 
    } 
}