Ped*_*pez 18 java xml spring factory-pattern spring-boot
我正在使用Spring Boot for Java独立应用程序.我有一个使用服务的bean.我想在运行时注入该服务的不同实现,基于Spring的属性文件中的属性(就此而言为4).
这听起来像工厂模式,但Spring也允许使用注释来解决问题,就像这样.
@Autowired @Qualifier("selectorProperty") private MyService myService;
Run Code Online (Sandbox Code Playgroud)
然后在beans.xml文件中我有一个别名,这样我就可以在@Qualifier中使用该属性.
<alias name="${selector.property}" alias="selectorProperty" />
Run Code Online (Sandbox Code Playgroud)
在我的不同实现中,我会有不同的限定符.
@Component("Selector1")
public class MyServiceImpl1
@Component("Selector2")
public class MyServiceImpl2
Run Code Online (Sandbox Code Playgroud)
application.properties
selector.property = Selector1
selector.property = Selector2
Run Code Online (Sandbox Code Playgroud)
而对于工厂模式,在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);
}
Run Code Online (Sandbox Code Playgroud)
然后在您的bean中,您可以使用类似的东西在运行时获得正确的实现,具体取决于属性的值.
@Value("${selector.property}") private String selectorProperty;
@Autowired private MyServiceFactory myServiceFactory;
private MyService myService;
@PostConstruct
public void postConstruct()
{
this.myService = myServiceFactory.getMyService(selectorProperty);
}
Run Code Online (Sandbox Code Playgroud)
但是这个解决方案的问题是我找不到一种方法来避免使用XML来定义工厂,我想只使用注释.
所以问题是,是否有一种方法可以仅使用注释来使用ServiceLocatorFactoryBean(或类似的东西),或者如果我不想在XML中定义bean,我是否被迫使用@Autowired @Qualifier方法?或者是否还有其他方法可以在运行时根据Spring 4避免使用XML的属性注入不同的服务?如果您的答案只是使用@Autowired @Qualifier别名,请说明为什么这比使用众所周知的工厂模式更好.
使用额外的XML迫使我@ImportResource("classpath:beans.xml")在我的Launcher类中使用,我也不愿意使用它.
谢谢.
我正在使用Spring配置文件
例如,使用dataSources使用它,您可以根据需要定义任意数量的dataSource
@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();
}
}
Run Code Online (Sandbox Code Playgroud)
并在运行时,通过指定
-Dspring.profiles.active = "我的资料"
您激活了一个或另一个配置(所有这些配置必须在主配置中导入,它们将根据活动配置文件被忽略).
这是一篇很好的文章:http: //spring.io/blog/2011/02/14/spring-3-1-m1-introducing-profile/
实际上,您可以在不使用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();
}
Run Code Online (Sandbox Code Playgroud)
然后你仍然可以照常使用工厂,但不涉及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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
25942 次 |
| 最近记录: |