当前位置: 首页 > 知识库问答 >
问题:

Spring Boot-在@Qualifier上使用可配置的值

娄森
2023-03-14

对于一个接口,我有两个实现,我想根据配置选择要使用的实现。限定符解决方案无法工作,因为它是在配置之前初始化的。我怎样才能做到这一点?

共有3个答案

王涵育
2023-03-14

我最终将两个实现自动装配添加到主端类中,然后为每个实现定义一个bean:

@Autowired
TypeOneImpl typeOneImpl
@Bean(name = "typeOneImpl")
public InterfaceRClass getTypeOneImpl()
{
    return typeOneImpl;
}

然后在另一个类中,我定义了一个配置字段

@Value("${myClass.type}")
private String configClassType;
// the below should be defined in constructor
private final InterfaceRClass interfaceRClassElement ;

并为其添加了一个带有@Autow的注释的setter:

@Autowired
public void setMyClassType(ApplicationContext context) {
    interfaceRClassElement = (InterfaceRClass) context.getBean(configClassType);
}

在配置中,值应该是typeOneImpl(为附加实现添加了typeTwoImpl)

穆飞星
2023-03-14

如果您稍微摆弄一下基于java的Spring配置,您可以根据配置值以编程方式决定正确的实现:

@Configuration
public class MyAppContext implements EnvironmentAware{

    private Environment env;

    @Override
    public void setEnvironment(final Environment env) {
       this.env = env;
    }

    @Bean
    public MyBeanByConfig myBeanByConfig(){
        String configValue = env.getProperty("mybean.config");

        if(configValue.equals("1")){
           return new MyBeanByConfigOne();
        }else{
           return new MyBeanByConfigTwo();
        }
    }
}

在限定符上,您可以输入:

@Qualifier("myBeanByConfig")

您可能还需要在configuration类中添加ComponentScan和PropertySource。

季嘉良
2023-03-14

我收到你的评论:

我有两个不同的作业实现,并且可以每月更改类型,因此如果可配置,则可以减少部署和代码更改。

你可能有这样的东西:

 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;}
 }

而且,如果我没说错的话,在同一个应用程序上下文中同时加载两个bean是没有意义的。

但如果是这样的话,那么限定符就不是合适的工作工具。

我建议使用集成到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);
    }
}

现在在application.properties(或yaml,无论你有什么)中定义:

 job.name = jobA # or jobB

当然,您可以使用更多来自业务领域的不言自明的名称,而不是jobA/jobB。

 类似资料:
  • 我正在用SpringBoot配置Consor,并在这里找到了一个文档。即使浏览了其他资源,也没有找到其他配置或场景。 因此,我很好奇当springboot应用程序与consul集成时是否只有这些配置可用。我想深入了解,有人能让我知道任何其他可用的属性吗?

  • 我知道在DispatcherServlet之外使用请求范围bean需要一些配置,并且已经阅读了http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes-oth,但是还没有成功: 对于Servlet3.0+,这可以通过WebApplicationIni

  • 我正在尝试将Apache shiro 1.7.0添加为安全管理器,您会发现我的配置类: shiro的pom.xml条目: 该项目编译成功,但我得到了上面的错误,而试图访问web应用程序,我感谢任何麻或建议。 启动Tomcat上下文时出错。异常:org.springframework.beans.factory.beancreationexception。消息:创建类路径资源[org/apache/

  • 下面是我的hibernate配置类。 当我通过spring boot运行这个bean时,我得到的错误是“预期的单个匹配bean但找到了2:datasource和DataSourceActiviti”。

  • <dependencyManagement> <dependencies> <dependency> <!--Import dependency management from SpringBoot--> <groupId>org.springframework.boot</groupId>

  • 我已经创建了一个应用程序使用Springboot和Hibernate,我想配置它的单元测试。 首先,这是DAO接口。 这是DAO接口的实现 然后我创建了一个测试类,如下所示 我已经将application.properties文件放在test和src目录的资源中。 我尝试运行此单元测试用例,但由于以下错误而失败: 那么我可以知道为DAO层配置单元测试的最佳方法吗?