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

如何从属性文件中读取限定符在Spring启动?

华景同
2023-03-14

我有一个限定词

public class TestController{
     @Autowired
     @Qualifier("jdbc")
     private JdbcTemplate jtm;
     //.....
}

限定符“jdbc”是定义为

@Bean(name = "jdbc")
@Autowired
public JdbcTemplate masterJdbcTemplate(@Qualifier("prod") DataSource prod) {
            return new JdbcTemplate(prod);
        }

这是返回该限定符的数据源并正常工作的。

现在,我想从应用程序中读取限定符名称。属性。所以我把代码改为

public class TestController{
     @Autowired
     @Qualifier("${database.connector.name}")
     private JdbcTemplate jtm;
     //.....

}

其中,数据库。连接器。在我的应用程序中,name=jdbc。属性。

但当我这样做的时候,这会产生一个错误

应用程序启动失败

说明:

main中的字段userService。Java语言RestTestController需要“org”类型的bean。springframework。jdbc。果心找不到JdbcTemplate“”。

行动:

考虑定义“org”类型的bean。springframework。jdbc。果心配置中的JdbcTemplate。

非常感谢您的帮助。

共有3个答案

凤高翰
2023-03-14

如果您保留@Qualifier("jdbc"),您可以通过提供不同的测试配置文件并为每个测试类加载所需的配置文件来更改注入的bean。

单喜
2023-03-14

正如@Hitant已经提到的默认QualifierCandidateResolver不解析属性。

但是你可以做一个,它可以:

import java.lang.annotation.Annotation;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.stereotype.Component;
@Component
public static class AutowireCandidateResolverConfigurer implements BeanFactoryPostProcessor {
    private static class EnvironmentAwareQualifierAnnotationAutowireCandidateResolver extends QualifierAnnotationAutowireCandidateResolver {

        private static class ResolvedQualifier implements Qualifier {
            private final String value;
            ResolvedQualifier(String value) { this.value = value; }
            @Override
            public String value() { return this.value; }
            @Override
            public Class<? extends Annotation> annotationType() { return Qualifier.class; }
        }

        @Override
        protected boolean checkQualifier(BeanDefinitionHolder bdHolder, Annotation annotation, TypeConverter typeConverter) {
            if (annotation instanceof Qualifier) {
                Qualifier qualifier = (Qualifier) annotation;
                if (qualifier.value().startsWith("${") && qualifier.value().endsWith("}")) {
                    DefaultListableBeanFactory bf = (DefaultListableBeanFactory) this.getBeanFactory();
                    ResolvedQualifier resolvedQualifier = new ResolvedQualifier(bf.resolveEmbeddedValue(qualifier.value()));
                    return super.checkQualifier(bdHolder, resolvedQualifier, typeConverter);
                }
            }
            return super.checkQualifier(bdHolder, annotation, typeConverter);
        }
    }

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        DefaultListableBeanFactory bf = (DefaultListableBeanFactory) beanFactory;
        bf.setAutowireCandidateResolver(new EnvironmentAwareQualifierAnnotationAutowireCandidateResolver());
    }
}

有了它,您将能够以您要求的方式使用限定符(${database.connector.name})

完整示例:

@SpringBootApplication
public class SO50208018Application {

    public static void main(String[] args) { SpringApplication.run(SO50208018Application.class, args); }

    interface MyBean { }
    static class MyBeanImpl1 implements MyBean { }
    static class MyBeanImpl2 implements MyBean { }

    @Bean @Qualifier("impl1")
    MyBean bean1() { return new MyBeanImpl1(); }

    @Bean @Qualifier("impl2")
    MyBean bean2() { return new MyBeanImpl2(); }


    @Component
    public static class AutowireCandidateResolverConfigurer implements BeanFactoryPostProcessor {
        // configurer from above
    }

    @Bean
    CommandLineRunner run(@Qualifier("${spring.application.bean}") MyBean bean) {
        return (args) -> System.out.println(bean.getClass().getName());
    }
}

使用Spring运行。应用bean=impl1:

com.stackoverflow.java.SO50208018Application$MyBeanImpl1

使用spring.application.bean=impl2运行:

com.stackoverflow.java.SO50208018Application$MyBeanImpl2
卜季萌
2023-03-14

限定符未解析占位符。您可以将TestController类编写为

public class TestController {

    @Value("${database.connector.name}")
    private String name;

    private JdbcTemplate jtm;

    @Autowired
    public void setJdbcTemplate(ApplicationContext context) {

        jtm = (JdbcTemplate) context.getBean(name);
    }
}
 类似资料:
  • 我必须从我的Spring启动项目的属性文件中读取一些字符串数组变量。我已经为数组创建了一个具有 getter 和 setter 方法的类。我不知道如何使用java 1.8从land.yml文件中获取这些字符串数组变量的值

  • 问题内容: 在发布此问题之前,我用Google搜索Spring项目(不是基于Web的项目)中的属性。我很困惑,因为每个人都在谈论application- context.xml并具有类似的配置 但是,我正在使用Spring进行普通的Java项目(没有Web应用程序之类的东西)。但是我想从属性文件中获取一些通用属性,并且需要在JAVA文件中使用。如何通过使用Spring / Spring注释实现此目

  • 每个人都知道如果我们想要读取属性文件,我们可以这样做: 但是,现在我有了一个类似于SpringBoot的框架。它可以将Spring与Mybatis集成在一起。 问题是前面的代码只能读取我的项目类路径文件,但我需要使用我的框架读取project属性文件。我是怎么做的?

  • 问题内容: 我正在用弹簧。我需要从属性文件中读取值。这是内部属性文件,而不是外部属性文件。属性文件可以如下。 我需要以传统方式从属性文件中读取这些值。如何实现呢?Spring 3.0是否有最新方法? 问题答案: 在你的上下文中配置PropertyPlaceholder: 然后,你引用bean中的属性: 编辑:更新了代码以使用逗号分隔的多个值来解析属性: 如果那不起作用,则可以定义一个带有属性的be

  • 下面是我在Spring引导应用程序中的yml文件 低于值访问是工作文件 但当我试图以下面的方式访问时,它会给出一个错误。 我检查了只有在添加“com.cloudimpl.outstack.runtime.EventRepositoryFactory”这一部分时才会出现错误。 我怎样才能解决这个问题??

  • 问题内容: 在我的目标文件夹中,有2个文件夹,lib和conf。所有的属性文件都放在conf文件夹中,而jars放在lib foulder中。 在Spring Boot之前,我们在spring.xml中使用以下配置来使用@value 但是在spring启动中,我不知道如何在Java代码中执行相同的操作。 我尝试了以下操作,但是没有用 问题答案: 问题的标题和描述让我有些困惑。希望我不会再让你对我的