如何使用@Value Spring 注释注入一个 Map?

如何使用 Spring 中的@Value 注释将属性文件中的值注入到 Map 中?

我的 Spring Java 类是,我尝试使用 $,但是得到以下错误消息:

无法自动连接字段: private java.util。映射 Test.standard; 嵌套的异常是 java.lang。IllegalArgumentException: 无法解析字符串值“ ${ com.test.standard }”中的占位符‘ com.test.standard’

@ConfigurationProperty("com.hello.foo")
public class Test {


@Value("${com.test.standard}")
private Map<String,Pattern> standard = new LinkedHashMap<String,Pattern>


private String enabled;


}

在. properties 文件中有以下属性

com.test.standard.name1=Pattern1
com.test.standard.name2=Pattern2
com.test.standard.name3=Pattern3
com.hello.foo.enabled=true
161156 次浏览

You can inject .properties as a map in your class using @Resource annotation.

If you are working with XML based configuration, then add below bean in your spring configuration file:

 <bean id="myProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:your.properties"/>
</bean>

For, Annotation based:

@Bean(name = "myProperties")
public static PropertiesFactoryBean mapper() {
PropertiesFactoryBean bean = new PropertiesFactoryBean();
bean.setLocation(new ClassPathResource(
"your.properties"));
return bean;
}

Then you can pick them up in your application as a Map:

@Resource(name = "myProperties")
private Map<String, String> myProperties;

I believe Spring Boot supports loading properties maps out of the box with @ConfigurationProperties annotation.

According that docs you can load properties:

my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com

into bean like this:

@ConfigurationProperties(prefix="my")
public class Config {


private List<String> servers = new ArrayList<String>();


public List<String> getServers() {
return this.servers;
}
}

I used @ConfigurationProperties feature before, but without loading into map. You need to use @EnableConfigurationProperties annotation to enable this feature.

Cool stuff about this feature is that you can validate your properties.

You can inject values into a Map from the properties file using the @Value annotation like this.

The property in the properties file.

propertyname={key1:'value1',key2:'value2',....}

In your code.

@Value("#{${propertyname}}")  private Map<String,String> propertyname;

Note the hashtag as part of the annotation.

Here is how we did it. Two sample classes as follow:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.annotation.EnableKafka;
@EnableKafka
@Configuration
@EnableConfigurationProperties(KafkaConsumerProperties.class)
public class KafkaContainerConfig {


@Autowired
protected KafkaConsumerProperties kafkaConsumerProperties;


@Bean
public ConsumerFactory<String, String> consumerFactory() {
return new DefaultKafkaConsumerFactory<>(kafkaConsumerProperties.getKafkaConsumerConfig());
}
...


@Configuration
@ConfigurationProperties
public class KafkaConsumerProperties {
protected Map<String, Object> kafkaConsumerConfig = new HashMap<>();


@ConfigurationProperties("kafkaConsumerConfig")
public Map<String, Object> getKafkaConsumerConfig() {
return (kafkaConsumerConfig);
}
...

To provide the kafkaConsumer config from a properties file, you can use: mapname[key]=value

//application.properties
kafkaConsumerConfig[bootstrap.servers]=localhost:9092, localhost:9093, localhost:9094
kafkaConsumerConfig[group.id]=test-consumer-group-local
kafkaConsumerConfig[value.deserializer]=org.apache.kafka.common.serialization.StringDeserializer
kafkaConsumerConfig[key.deserializer=org.apache.kafka.common.serialization.StringDeserializer

To provide the kafkaConsumer config from a yaml file, you can use "[key]": value In application.yml file:

kafkaConsumerConfig:
"[bootstrap.servers]": localhost:9092, localhost:9093, localhost:9094
"[group.id]": test-consumer-group-local
"[value.deserializer]": org.apache.kafka.common.serialization.StringDeserializer
"[key.deserializer]": org.apache.kafka.common.serialization.StringDeserializer

I had a simple code for Spring Cloud Config

like this:

In application.properties

spring.data.mongodb.db1=mongodb://test@test1.com

spring.data.mongodb.db2=mongodb://test@test2.com

read

@Bean(name = "mongoConfig")
@ConfigurationProperties(prefix = "spring.data.mongodb")
public Map<String, Map<String, String>> mongoConfig() {
return new HashMap();
}

use

@Autowired
@Qualifier(value = "mongoConfig")
private Map<String, String> mongoConfig;


@Bean(name = "mongoTemplates")
public HashMap<String, MongoTemplate> mongoTemplateMap() throws UnknownHostException {
HashMap<String, MongoTemplate> mongoTemplates = new HashMap<>();
for (Map.Entry<String, String>> entry : mongoConfig.entrySet()) {
String k = entry.getKey();
String v = entry.getValue();
MongoTemplate template = new MongoTemplate(new SimpleMongoDbFactory(new MongoClientURI(v)));
mongoTemplates.put(k, template);
}
return mongoTemplates;
}

To get this working with YAML, do this:

property-name: '{
key1: "value1",
key2: "value2"
}'

Following worked for me:

SpingBoot 2.1.7.RELEASE

YAML Property (Notice value sourrounded by single quotes)

property:
name: '{"key1": false, "key2": false, "key3": true}'

In Java/Kotlin annotate field with (Notice use of #) (For java no need to escape '$' with '\')

@Value("#{\${property.name}}")

You can use below code.

Below code for application.yml

my:
mapValues:
dbData: '{
"connectionURL": "http://tesst:3306",
"userName": "myUser",
"password": "password123"
}'

to access these key and values using @Value annotation use below java code.

@Value("#{${my.mapValues.dbData}}")
private Map<String,String> dbValues;