java 在Spring中使用applicationContext.getBean()创建bean时,如何指定要使用哪个组件?

z9smfwbn  于 2023-02-02  发布在  Java
关注(0)|答案(4)|浏览(121)

我有以下类和接口:

public interface GamingSoftware {
    public void up();
    public void down();
    public void left();
    public void right();
}

@Component
public class SuperMario implements GamingSoftware {
    public void up() { System.out.println("Super Mario: up"); }
    public void down() { System.out.println("Super Mario: down"); }
    public void left() {  System.out.println("Super Mario: left"); }
    public void right() { System.out.println("Super Mario: right"); }
}

@Component
public class SuperContra implements GamingSoftware {
    public void up() { System.out.println("Super Contra: up"); }
    public void down() { System.out.println("Super Contra: down"); }
    public void left() {  System.out.println("Super Contra: left"); }
    public void right() { System.out.println("Super Contra: right"); }
}

@Component
public class GameRunner {
    @Autowired
    private GamingSoftware game;
    public GameRunner(GamingSoftware game) {
        this.game = game;
    }
    public void run() {
        game.up();
        game.down();
        game.left();
        game.right();
    }
}

@SpringBootApplication
public class GamingDevice {

    public static void main(String[] args) {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(GamingDevice.class, args);
        GameRunner gameRunner = applicationContext.getBean(GameRunner.class);
        gameRunner.run();
    }

}

在获取bean applicationContext.getBean(GameRunner.class)时,我希望能够指定游戏来示例化GameRunner类中的GamingSoftware变量。
当我运行上面的代码时,它给了我一个错误,比如,游戏运行器的构造函数需要一个bean,但是2找到了SuperMarioSuperContra
如何指定在applicationContext.getBean()方法中使用哪个组件?

fwzugrvs

fwzugrvs1#

在springboot中,上下文在applicationContext.getBean()时不加载,上下文在SpringApplication.run(GamingDevice.class,args)中加载,因此在该行中是抛出异常的时候。
要运行,您必须删除GamingSoftware上的@Autowired并使用设置属性加载它:

@Component
    public class GameRunner {
    
        private GamingSoftware game;
        
        public void run() {
            game.up();
            game.down();
            game.left();
            game.right();
        }
    
        public GamingSoftware getGame() {
            return game;
        }
    
        public void setGame(GamingSoftware game) {
            this.game = game;
        }
        
    }

@SpringBootApplication
public class GamingDevice {

    public static void main(String[] args) {
         ConfigurableApplicationContext applicationContext = SpringApplication.run(GamingDevice.class, args);
         GameRunner gameRunner = applicationContext.getBean(GameRunner.class);
         gameRunner.setGame(applicationContext.getBean("superContra",GamingSoftware.class));
         gameRunner.run();
    }

}
tgabmvqs

tgabmvqs2#

函数getBean()支持给supplier bean构造函数的参数,调用getBean(Class, Args...)时可以传递正确的GamingSoftware示例
在此处阅读有关get beans的更多信息

xxls0lw8

xxls0lw83#

例如,您可以在 application.properties(或application.yml) 中创建属性
myapp.gametype=mario
然后添加到@Component注解@ConditionalOnProperty中

@Component
@ConditionalOnProperty(name = "myapp.gametype", havingValue = "mario")
public class SuperMario implements GamingSoftware {
    public void up() { System.out.println("Super Mario: up"); }
    public void down() { System.out.println("Super Mario: down"); }
    public void left() {  System.out.println("Super Mario: left"); }
    public void right() { System.out.println("Super Mario: right"); }
}

@Component
@ConditionalOnProperty(name = "myapp.gametype", havingValue = "contra")
public class SuperContra implements GamingSoftware {
    public void up() { System.out.println("Super Contra: up"); }
    public void down() { System.out.println("Super Contra: down"); }
    public void left() {  System.out.println("Super Contra: left"); }
    public void right() { System.out.println("Super Contra: right"); }
}

下一次Spring将只创建一个GamingSoftware接口的Bean,这取决于您的属性的值。

vsnjm48y

vsnjm48y4#

Bean是使用基于具体类名的名称创建的(第一个字母小写)。

applicationContext.getBean(“superMario”)

相关问题