英文:
Dynamically inject service implementation with Spring
问题
以下是您要翻译的内容:
"I've already gone through some tips on how to do this, like this one: stack overflow; but my problem is that my own implementation needs other things to be injected in it. Here's the example:
public interface MyService {}
public class ServiceImplA implements MyService {
@Autowired
private final SomeStuffA a_stuff;
}
public class ServiceImplB implements MyService {
@Autowired
private final SomeStuffB b_stuff;
}
@Configuration
public class SpringConfig {
@Bean
@Scope("singleton")
public MyService getService() {
boolean useA = // read config file and decide impl
return useA ? new ServiceImplA() : new ServiceImplB();
// I can't instantiate this, so i need them to be injected as well
}
}
I'm familiar with Google Guice, where I would do something like this:
bind(MyService.class).to(useA ? ServiceImplA.class : ServiceImplB.class);
So, I need a way to do this using Spring
英文:
I've already gone through some tips on how to do this, like this one: stack overflow; but my problem is that my own implementation needs other things to be injected in it. Here's the example:
public interface MyService {}
public class ServiceImplA implements MyService {
@Autowired
private final SomeStuffA a_stuff;
}
public class ServiceImplB implements MyService {
@Autowired
private final SomeStuffB b_stuff;
}
@Configuration
public class SpringConfig {
@Bean
@Scope("singleton")
public MyService getService() {
boolean useA = // read config file and decide impl
return useA ? new ServiceImplA() : new ServiceImplB();
// I can't instantiate this, so i need them to be injected as well
}
}
I'm familiar with Google Guice, where I would do something like this:
bind(MyServicle.class).to(useA ? ServiceImplA.class : ServiceImplB.class);
So, I need a way to do this using Spring
答案1
得分: 2
我认为你的问题在于你的基类 MyService
没有标记任何配置文件。
当你定义配置文件时,具有这种规范的 bean 会覆盖实现相同接口但没有配置文件定义的 bean。然而,这种方式是行不通的。
在使用活动配置文件 X
时,Spring 会启动所有没有针对任何配置文件的 bean,以及针对当前配置文件的 bean。在你的情况下,你可以进行明智的选择。
我认为,如果你想使用配置文件,你至少应该定义两个:A
和 B
(名称仅为示例)。
现在将 ServiceImplA
标记为 A
,将 ServiceImplB
标记为 B
:
@Service
@Profile("A")
public class ServiceImplA implements MyService { ... }
// 一些开发实现
@Service
@Profile("B")
public class ServiceImplB implements MyService { ... }
关于配置文件的更多信息,你可以在这里
找到。
英文:
I think your problem is that your base class MyService
is not marked for any profile.
When you define profile the beans that have such specification will override beans that implement the same interface and do not have profile definition. This does not work this way.
When working with active profile X
spring starts all beans that are not targeted for any profile and beans targeted for current profile. In your case you can choose wisely.
I think that if you want to use profiles you should define at least 2: A
and B
(the names are taken just for example.)
Now mark ServiceImplA
as A
and ServiceImplB
as B
:
@Service
@Profile("A")
public ServiceImplA interface MyService { ... }
and some development implementation
@Service
@Profile("B")
public ServiceImplB interface MyService { ... }
More about profiling you will get here
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论