使用new创建对象时,Spring注入的bean为null,如何解决呢? [英] Spring Injected bean null when creating an object with new ,how to solve it?

查看:821
本文介绍了使用new创建对象时,Spring注入的bean为null,如何解决呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an application , and now I am trying to use Spring to refactor it, and I have problem when creating object using new, but I don't know how to solve it.

这是现实:

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

I have a Controller, need a CommandService instance, and the CommandService need a RoomService to create AbstractRoom instances to put into RoomService instance's hashmap.

我有两种 AbstractRoom 称为RoomA,RoomB,它们从 AbstractRoom ,而 AbstractRoom 需要 GameService 实例。

I have two kinds of AbstractRoom called RoomA, RoomB, and they extend from AbstractRoom, and AbstractRoom needs GameService instance.

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

I will pass a param from commandService to roomService so that the roomservice can create a right room instance.

现在的问题是,我使用roomservice.createRoom创建了一个房间使用 new 来完成。因此,Spring无法将GameService注入我的抽象房间,因此我没有使用gameService。

The problem now, is that I use roomservice.createRoom to create a room which uses new to do that. So Spring can not inject GameService to my Abstract Room thus I have a null gameService.

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

But CommandService will get some input from user and to delegate to RoomService to create a room for it, so I don't know which Room Instance will be created until the user input something:

CommandService。 java:

CommandService.java:

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

这是我如何从RoomService.java创建Room :

Here is how I createRoom from 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

Here is my 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解决了这个问题,并返回了实例

Eventually, I solve this problem with letting AbstractRoom as a bean with scope = prototype, and return the instance from 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 ,然后从容器中获取房间。

And in RoomService.java , inject an ApplicationContext, and get Room from the container.

public class RoomService {

    @Autowired
    private ApplicationContext ctx;

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

这篇关于使用new创建对象时,Spring注入的bean为null,如何解决呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆