簡體   English   中英

在 spring 中使用 applicationContext.getBean() 創建 bean 時如何指定要使用的組件?

[英]How do I specify which component to use while creating the bean using applicationContext.getBean() in spring?

我有以下類和接口:

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 class 中實例化GamingSoftware變量。

當我運行上面的代碼時,它給了我一個錯誤,比如,Constructor for game runner required a single bean but 2 found SuperMario and SuperContra

如何指定在我的applicationContext.getBean()方法中使用哪個組件?

在 springboot 中,在 applicationContext.getBean() 時不加載上下文。 上下文在 SpringApplication.run(GamingDevice.class, args) 中加載,因此在該行中是拋出異常的時間。

對於 runnig,您必須消除 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();
    }

}

function getBean()支持供應商 bean 構造函數的參數。 您可以在調用getBean(Class, Args...)時傳遞正確的 GamingSoftware 實例

在此處閱讀有關獲取豆子的更多信息

例如,您可以在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,這取決於您的屬性有什么價值。

Bean 的創建名稱基於具體的 class 名稱(首字母小寫)。 嘗試

applicationContext.getBean(“superMario”)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM