use*_*666 5 java spring spring-boot
我有一个接口的两个实现,我想根据配置选择要使用的实现。限定符解决方案不起作用,因为它在配置之前已初始化。我怎样才能做到这一点?
Mar*_*nik 11
我有你的评论:
我有两个不同的作业实现,并且每个月都可以更改类型,因此如果可配置,则可以减少部署和代码更改。
你可能有这样的事情:
interface Job {
void foo();
}
class JobA implements Job {
void foo() {...}
}
class JobB implements Job {
void foo() {...}
}
class JobExecutor {
Job job;
// autowired constructor
public JobExecutor(Job job) {this.job = job;}
}
Run Code Online (Sandbox Code Playgroud)
而且,如果我没猜错的话,在同一个应用程序上下文中同时加载两个 bean 是没有意义的。
但如果是这样,那么@Qualifier就不是适合这项工作的工具。
我建议使用集成到 spring boot 中的条件:
@Configuration
public class MyConfiguration {
@ConditionalOnProperty(name = "job.name", havingValue = "jobA")
@Bean
public Job jobA() {
return new JobA();
}
@ConditionalOnProperty(name = "job.name", havingValue = "jobB")
@Bean
public Job jobB() {
return new JobB();
}
@Bean
public JobExecutor jobExecutor(Job job) {
return new JobExecutor(job);
}
}
Run Code Online (Sandbox Code Playgroud)
现在在application.properties(或任何你拥有的 yaml 中)定义:
job.name = jobA # or jobB
Run Code Online (Sandbox Code Playgroud)
当然,jobA/jobB您可能会使用来自您的业务领域的更多不言自明的名称来代替。
我最终将两个自动装配的实现添加到主应用程序类中,然后为每个实现定义一个 bean:
@Autowired
TypeOneImpl typeOneImpl
@Bean(name = "typeOneImpl")
public InterfaceRClass getTypeOneImpl()
{
return typeOneImpl;
}
Run Code Online (Sandbox Code Playgroud)
然后在另一个类中我定义了一个配置字段
@Value("${myClass.type}")
private String configClassType;
// the below should be defined in constructor
private final InterfaceRClass interfaceRClassElement ;
Run Code Online (Sandbox Code Playgroud)
并使用 @Autowired 注释为其添加了一个设置器:
@Autowired
public void setMyClassType(ApplicationContext context) {
interfaceRClassElement = (InterfaceRClass) context.getBean(configClassType);
}
Run Code Online (Sandbox Code Playgroud)
在配置中,该值应该是typeOneImpl(添加typeTwoImpl是为了额外的实现)
| 归档时间: |
|
| 查看次数: |
3167 次 |
| 最近记录: |