繁体   English   中英

使用new创建对象时,Spring注入的bean为null,如何解决呢?

[英]Spring Injected bean null when creating an object with new ,how to solve it?

我有一个应用程序,现在我正在尝试使用Spring对其进行重构,并且在使用new创建对象时遇到了问题,但是我不知道如何解决它。

这是房地产:

我有一个Controller ,需要一个CommandService实例,而CommandService需要一个RoomService来创建将AbstractRoom实例放入RoomService实例的哈希图中。

我有两种AbstractRoom称为RoomA和RoomB,它们是从AbstractRoom扩展而来的,并且AbstractRoom需要GameService实例。

我将参数从commandService传递给roomService,以便roomservice可以创建正确的房间实例。

现在的问题是,我使用roomservice.createRoom创建了一个使用new来执行此操作的房间。 所以Spring不能将GameService注入我的Abstract Room,因此我有一个空的gameService。

但是CommandService将从用户那里得到一些输入,并委托给RoomService为其创建一个房间,因此,在用户输入内容之前,我不知道将创建哪个Room Instance:

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
    }

最终,我通过让AbstractRoom作为具有scope = prototype的bean来解决此问题,并从roomservice 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 ,然后从容器中获取Room。

public class RoomService {

    @Autowired
    private ApplicationContext ctx;

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM