lev*_*ied 86 java spring spring-boot
我有一个带有以下内容的Spring Boot应用程序application.yml- 基本上从这里开始:
info:
build:
artifact: ${project.artifactId}
name: ${project.name}
description: ${project.description}
version: ${project.version}
Run Code Online (Sandbox Code Playgroud)
我可以注入特定的值,例如
@Value("${info.build.artifact}") String value
Run Code Online (Sandbox Code Playgroud)
但是,我想注入整个地图,例如:
@Value("${info}") Map<String, Object> info
Run Code Online (Sandbox Code Playgroud)
是(或类似的)可能吗?显然,我可以直接加载yaml,但是想知道Spring是否已经支持了某些东西.
rak*_*sja 93
下面的解决方案是@Andy Wilkinson解决方案的简写,除了它不必使用单独的类或带@Bean注释的方法.
application.yml:
input:
name: raja
age: 12
somedata:
abcd: 1
bcbd: 2
cdbd: 3
Run Code Online (Sandbox Code Playgroud)
SomeComponent.java:
@Component
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "input")
class SomeComponent {
@Value("${input.name}")
private String name;
@Value("${input.age}")
private Integer age;
private HashMap<String, Integer> somedata;
public HashMap<String, Integer> getSomedata() {
return somedata;
}
public void setSomedata(HashMap<String, Integer> somedata) {
this.somedata = somedata;
}
}
Run Code Online (Sandbox Code Playgroud)
我们可以同时兼顾@Value注释@ConfigurationProperties,没有任何问题.但是吸气剂和孵化器很重要,@EnableConfigurationProperties必须要有@ConfigurationProperties工作.
我从@Szymon Stepniak提供的groovy解决方案中尝试了这个想法,认为它对某人有用.
And*_*son 63
您可以使用@ConfigurationProperties以下方式注入地图:
import java.util.HashMap;
import java.util.Map;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
@EnableConfigurationProperties
public class MapBindingSample {
public static void main(String[] args) throws Exception {
System.out.println(SpringApplication.run(MapBindingSample.class, args)
.getBean(Test.class).getInfo());
}
@Bean
@ConfigurationProperties
public Test test() {
return new Test();
}
public static class Test {
private Map<String, Object> info = new HashMap<String, Object>();
public Map<String, Object> getInfo() {
return this.info;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在问题中使用yaml运行此操作会产生:
{build={artifact=${project.artifactId}, version=${project.version}, name=${project.name}, description=${project.description}}}
Run Code Online (Sandbox Code Playgroud)
有多种选项可用于设置前缀,控制缺少属性的处理方式等.有关详细信息,请参阅javadoc.
Szy*_*iak 16
我今天遇到了同样的问题,但不幸的是Andy的解决方案对我不起作用.在Spring Boot 1.2.1.RELEASE中它更容易,但你必须要注意一些事情.
这是我的有趣部分application.yml:
oauth:
providers:
google:
api: org.scribe.builder.api.Google2Api
key: api_key
secret: api_secret
callback: http://callback.your.host/oauth/google
Run Code Online (Sandbox Code Playgroud)
providersmap只包含一个map条目,我的目标是为其他OAuth提供程序提供动态配置.我想将此映射注入到一个服务中,该服务将根据此yaml文件中提供的配置初始化服务.我最初的实施是:
@Service
@ConfigurationProperties(prefix = 'oauth')
class OAuth2ProvidersService implements InitializingBean {
private Map<String, Map<String, String>> providers = [:]
@Override
void afterPropertiesSet() throws Exception {
initialize()
}
private void initialize() {
//....
}
}
Run Code Online (Sandbox Code Playgroud)
启动应用程序后,providers映射OAuth2ProvidersService未初始化.我尝试了Andy建议的解决方案,但它没有用.我在该应用程序中使用Groovy,因此我决定删除private并让Groovy生成getter和setter.所以我的代码看起来像这样:
@Service
@ConfigurationProperties(prefix = 'oauth')
class OAuth2ProvidersService implements InitializingBean {
Map<String, Map<String, String>> providers = [:]
@Override
void afterPropertiesSet() throws Exception {
initialize()
}
private void initialize() {
//....
}
}
Run Code Online (Sandbox Code Playgroud)
在那之后,一切都变得很有效.
虽然有一件事值得一提.在我开始工作之后,我决定创建这个字段,private并在setter方法中为setter提供直接参数类型.不幸的是它不会那样.它导致org.springframework.beans.NotWritablePropertyException消息:
Invalid property 'providers[google]' of bean class [com.zinvoice.user.service.OAuth2ProvidersService]: Cannot access indexed value in property referenced in indexed property path 'providers[google]'; nested exception is org.springframework.beans.NotReadablePropertyException: Invalid property 'providers[google]' of bean class [com.zinvoice.user.service.OAuth2ProvidersService]: Bean property 'providers[google]' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
Run Code Online (Sandbox Code Playgroud)
如果您在Spring Boot应用程序中使用Groovy,请记住这一点.
Con*_*ant 13
在直接 @Value 注入的情况下,最优雅的方法是将键值编写为内联 json(使用 ' 和 " 字符以避免繁琐的转义)并使用 SPEL 解析它:
#in yaml file:
my:
map:
is: '{ "key1":"val1",
"key2":"val2" }'
Run Code Online (Sandbox Code Playgroud)
在您的 @Component 或 @Bean 中:
@Component
public class MyClass{
@Value("#{${my.map.is}}")
Map<String,String> myYamlMap;
}
Run Code Online (Sandbox Code Playgroud)
对于更方便的 YAML 语法,您可以完全避免 json 大括号,直接键入键值对
my:
map:
is: '"a":"b", "foo":"bar"'
Run Code Online (Sandbox Code Playgroud)
并将缺少的大括号直接添加到 @Value SPEL 表达式中:
@Value("#{{${my.map.is}}}")
Map<String,String> myYamlMap;
Run Code Online (Sandbox Code Playgroud)
该值将从 yaml 解析,环绕花括号将与其连接,最后 SPEL 表达式将字符串解析为映射。
小智 10
要从配置中检索地图,您将需要配置类。不幸的是,@ Value注释无法解决问题。
Application.yml
entries:
map:
key1: value1
key2: value2
Run Code Online (Sandbox Code Playgroud)
配置类:
@Component
@ConfigurationProperties("entries")
@Getter
@Setter
public static class MyConfig {
private Map<String, String> map;
}
Run Code Online (Sandbox Code Playgroud)
使用@Value 从 application.yml属性中提取Map 的解决方案编码为多行
应用程序.yml
other-prop: just for demo
my-map-property-name: "{\
key1: \"ANY String Value here\", \
key2: \"any number of items\" , \
key3: \"Note the Last item does not have comma\" \
}"
other-prop2: just for demo 2
Run Code Online (Sandbox Code Playgroud)
在这里,我们的地图属性“my-map-property-name”的值以JSON格式存储在一个字符串中 ,我们在行尾使用\ 实现了多行
我的JavaClass.java
import org.springframework.beans.factory.annotation.Value;
public class myJavaClass {
@Value("#{${my-map-property-name}}")
private Map<String,String> myMap;
public void someRandomMethod (){
if(myMap.containsKey("key1")) {
//todo...
} }
}
Run Code Online (Sandbox Code Playgroud)
更多解释
\在 yaml 中用于将字符串分成多行
\"是 yaml 字符串中 "(quote) 的转义字符
yaml 中的{key:value} JSON 将被 @Value 转换为 Map
#{ }是SpEL 表达式,可以在@Value 中使用,转换json int Map 或Array / list参考
在 Spring Boot 项目中测试
| 归档时间: |
|
| 查看次数: |
119019 次 |
| 最近记录: |