我正在使用 Spring Boot 1.4.3 和新的类型安全属性。目前,我已经使用 Spring 成功/自动地将多个属性(例如
my.nested.thing1
)映射到如下所示的类:
@ConfigurationProperties(prefix="my")
public class My {
Nested nested = new Nested();
public static class Nested {
String thing1;
String thing2;
//getters and setters....
}
}
我的问题是,如何以编程方式列出
@ConfigurationProperties
类中所有可能的属性?类似于 Spring 在 https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html 列出所有通用属性的方式。我要打印:
my.nested.thing1
my.nested.thing2
现在我正在手动维护一个列表,但这使得每当我们更改或添加属性时都变得非常困难。
在深入研究 Spring Boot 源代码后发现了这一点:
@PostConstruct
public void printTheProperties() {
String prefix = AnnotationUtils.findAnnotation(My.class, ConfigurationProperties.class).prefix();
System.out.println(getProperties(My.class, prefix));
}
/**
* Inspect an object recursively and return the dot separated property paths.
* Inspired by org.springframework.boot.bind.PropertiesConfigurationFactory.getNames()
*/
private Set<String> getProperties(Class target, String prefix) {
Set<String> names = new LinkedHashSet<String>();
if (target == null) {
return names;
}
if (prefix == null) {
prefix = "" ;
}
PropertyDescriptor[] descriptors = BeanUtils.getPropertyDescriptors(target);
for (PropertyDescriptor descriptor : descriptors) {
String name = descriptor.getName();
if (name.equals("class")) {
continue;
}
if (BeanUtils.isSimpleProperty(descriptor.getPropertyType())) {
names.add(prefix + "." + name);
} else {
//recurse my pretty, RECURSE!
Set<String> recursiveNames = getProperties(descriptor.getPropertyType(), prefix + "." + name);
names.addAll(recursiveNames);
}
}
return names;
}
为了解决列出所有可能选项的问题,我正在利用键值属性。值得注意的是,我使用的是 Spring Boot 3.0.5 版本和 Lombok 与 Java 17 结合使用,这与您原来的问题不同。
我的房产课
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
@Configuration
@ConfigurationProperties(prefix="my")
public class My {
private Map<String, Nested> nested;
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public static class Nested {
String field1;
String field2;
//getters and setters....
}
}
我的application.yaml,但是,你可以使用application.properties
my:
nested:
thing1:
field1: "field1"
field2: "field2"
thing2:
field1: "field1"
field2: "field2"
如何注入服务。
@RequiredArgsConstructor
@Component
public class My Service {
private final My my;
public void method(String thing){
final var my.getNested().get(thing)
}
}