JavaスタンドアロンアプリケーションにSpring Bootを使用しています。サービスを利用するBeanがあります。プロパティファイルのプロパティに基づいて、実行時にそのサービスのさまざまな実装を注入したいです。 Springで(その点で4つ)。
これはFactoryパターンのように聞こえますが、Springではこのように注釈を使用して問題を解決することもできます。
_@Autowired @Qualifier("selectorProperty") private MyService myService;
_
次に、beans.xmlファイルにはエイリアスがあり、@ Qualifierのプロパティを使用できます。
_<alias name="${selector.property}" alias="selectorProperty" />
_
また、実装が異なると、修飾子も異なります。
_@Component("Selector1")
public class MyServiceImpl1
@Component("Selector2")
public class MyServiceImpl2
_
application.properties
_selector.property = Selector1
selector.property = Selector2
_
一方、ファクトリパターンに関しては、SpringではServiceLocatorFactoryBeanを使用して、同じ機能を提供するファクトリを作成できます。
_<bean
class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean"
id="myServiceFactory">
<property
name="serviceLocatorInterface"
value="my.company.MyServiceFactory">
</property>
</bean>
public interface MyServiceFactory
{
MyService getMyService(String selector);
}
_
そして、Beanでこのようなものを使用して、プロパティの値に応じて実行時に適切な実装を取得できます。
_@Value("${selector.property}") private String selectorProperty;
@Autowired private MyServiceFactory myServiceFactory;
private MyService myService;
@PostConstruct
public void postConstruct()
{
this.myService = myServiceFactory.getMyService(selectorProperty);
}
_
しかし、このソリューションの問題は、XMLを使用してファクトリーを定義することを避ける方法を見つけることができず、注釈のみを使用したいことです。
だから質問は、アノテーションのみを使用してServiceLocatorFactoryBean(または同等のもの)を使用する方法がありますか、またはXMLでBeanを定義したくない場合は@Autowired @Qualifier方法を使用することを強制されますか?または、Spring 4でXMLを回避して、プロパティに基づいて実行時に異なるサービスを注入する他の方法はありますか?エイリアスで_@Autowired @Qualifier
_を使用するだけの場合、よく知られているファクトリパターンを使用するよりも優れている理由を教えてください。
余分なXMLを使用すると、Launcherクラスで@ImportResource("classpath:beans.xml")
を使用せざるを得なくなり、どちらも使用しません。
ありがとう。
実際、XMLなしでServiceLocatorFactoryを使用するには、構成ファイルでBeanとして宣言します。
@Bean
public ServiceLocatorFactoryBean myFactoryServiceLocatorFactoryBean()
{
ServiceLocatorFactoryBean bean = new ServiceLocatorFactoryBean();
bean.setServiceLocatorInterface(MyServiceFactory.class);
return bean;
}
@Bean
public MyServiceFactory myServiceFactory()
{
return (MyServiceFactory) myFactoryServiceLocatorFactoryBean().getObject();
}
その後、通常どおりファクトリを使用できますが、XMLは関係しません。
@Value("${selector.property}") private String selectorProperty;
@Autowired @Qualifier("myServiceFactory") private MyServiceFactory myServiceFactory;
private MyService myService;
@PostConstruct
public void postConstruct()
{
this.myService = myServiceFactory.getMyService(selectorProperty);
}
Springプロファイルを使用しています
たとえば、dataSourcesを使用すると、好きなだけdataSourcesを定義できます
@Configuration
@Profile("dev")
public class StandaloneDataConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.addScript("classpath:com/bank/config/sql/test-data.sql")
.build();
}
}
@Configuration
@Profile("cloud")
public class CloudDataConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.addScript("classpath:com/bank/config/sql/test-data.sql")
.build();
}
}
そして、実行時に、指定することにより
-Dspring.profiles.active = "myProfile"
1つまたは別の構成をアクティブにします(それらはすべてメイン構成にインポートする必要があり、アクティブなプロファイルに基づいて無視されます)。
ここに良い記事があります: http://spring.io/blog/2011/02/14/spring-3-1-m1-introducing-profile/