啟動 Spring Boot 應用程式時,如何將 Java 類的實體動態傳遞給 Spring 配置?
我有一個在實體化時ThirdPartyService需要的SomeConfig。現在,我想使用自定義包裝此服務ServiceWrapper,然后使用 Spring Boot 以編程方式啟動它,而用戶不ServiceWrapper知道在幕后使用了 Spring Boot,ServiceWrapperTest讓您了解我打算如何使用它:
@Service
public class ThirdPartyService {
private final SomeConfig someConfig;
@Autowired
public ThirdPartyService(final SomeConfig someConfig) {
this.someConfig = someConfig;
}
void start() {
// reads values from someConfig and starts the service
}
void stop() {
// stops the service
}
}
public class SomeConfig {
// getters and setters omitted
}
@SpringBootApplication
public class ServiceWrapper {
private ThirdPartyService thirdPartyService;
public ServiceWrapper() {
}
public void start(SomeConfig someConfig) {
// how can I pass someConfig to Spring Boot?
thirdPartyService = SpringApplication.run(ThirdPartyService.class).getBean(ThirdPartyService.class);
}
public void stop() {
if (thirdPartyService != null) {
thirdPartyService.stop();
}
}
}
class ServiceWrapperTest {
@Test
void testStartAndStop() {
SomeConfig someConfig = new SomeConfig();
ServiceWrapper serviceWrapper = new ServiceWrapper(someConfig);
serviceWrapper.start();
serviceWrapper.stop();
}
}
不出所料,測驗失敗并出現以下錯誤:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.example.test.ThirdPartyService required a bean of type 'com.example.test.SomeConfig' that could not be found.
Action:
Consider defining a bean of type 'com.example.test.SomeConfig' in your configuration.
如何將SomeConfig實體傳遞給 Spring Beot 以便它有資格進行自動裝配?是否可以使用@Bean,@Configuration或類似的(我不這么認為)?
Spring Boot 2.6.1 版
uj5u.com熱心網友回復:
您可以使用 anApplicationContextInitializer使現有實體SomeConfig作為 bean 可用:
public void start(SomeConfig someConfig) {
SpringApplication application = new SpringApplication(ServiceWrapper.class);
application.addInitializers(new ApplicationContextInitializer<ConfigurableApplicationContext>() {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
applicationContext.getBeanFactory().registerSingleton("someConfig", someConfig);
}
});
ThirdPartyService service = application.run().getBean(ThirdPartyService.class);
// Use service as needed
}
uj5u.com熱心網友回復:
你是這個意思嗎:
@SpringBootApplication
public class ServiceWrapper {
@Bean
SomeConfig getSomeConfig() {
return someConfig;
}
private static SomeConfig someConfig; // really not thread safe
private ApplicationContext context;
public void start(SomeConfig someConfig) {
this.someConfig = someConfig;
this.context = SpringApplication.run(ServiceWrapper.class);
// do whatever you want with ThirdPartyService
ThirdPartyService service = this.context.getBean(ThirdPartyService.class);
}
public void stop() {
this.context.close();
}
}
通過這種方式,您可以將 SomeConfig 設為 Spring 的 bean 并使用它來連接您的背景關系,但您不需要更改 SomeConfig 中的任何代碼。然后您已經填充了 ThirdPartyService,您可以使用 getter 回傳它。
uj5u.com熱心網友回復:
如果它只是一個第三方類并在ServiceWrapper 中執行標準建構式或欄位注入,則可以使用@Component對其進行注釋。同樣從 Spring 5.2 開始,您不必使用@Autowired顯式注釋依賴項注入。
@Service
public class ThirdPartyService {
private final SomeConfig someConfig;
public ThirdPartyService(final SomeConfig someConfig) {
this.someConfig = someConfig;
}
void start() {
// reads values from someConfig and starts the service
}
void stop() {
// stops the service
}
}
@Component
public class SomeConfig {
// getters and setters omitted
}
也就是說,如果我正確理解了您的問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/377912.html
