![](/img/trans.png)
[英]Dynamically autowire a bean without using ApplicationContext.getBean() in Spring
[英]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.