Che*_*rry 9 java spring configurationproperty spring-boot
要使用@ConfigurationProperties注释,必须创建一个带有getter和setter的类:
@ConfigurationProperties(prefix = "some")
public class PropertiesConfig {
private boolean debug;
public boolean isDebug() {
return debug;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
}
Run Code Online (Sandbox Code Playgroud)
但这会导致某人试图通过调用以下方法修改此值的情况:
@Autowire
private PropertiesConfig config;
//....
config.setDebug(true);
Run Code Online (Sandbox Code Playgroud)
有没有办法在@ConfigurationProperties没有setter和外部解析器/ reader类的情况下创建带注释的类?
从 Spring Boot 2.2 开始,终于可以定义用@ConfigurationProperties. 非常感谢 Spring 开发人员不断改进他们的框架。
该文档显示了一个示例。
您只需要声明一个带有要绑定的字段的构造函数(而不是 setter 方式):
@ConstructorBinding
@ConfigurationProperties(prefix = "some")
public class PropertiesConfig {
private boolean debug;
public AcmeProperties(boolean enabled) {
this.enabled = enabled;
}
public boolean isDebug() {
return debug;
}
}
Run Code Online (Sandbox Code Playgroud)
注意 1:您必须定义一个且唯一一个带有要绑定的参数的构造函数:
在此设置中,必须使用您希望绑定的属性列表定义一个且仅一个构造函数,并且不能绑定除构造函数中的属性之外的其他属性。
注 2:@DefaultValue引入 a 是为了定义不可变属性绑定的默认值。
可以使用 @DefaultValue 指定默认值,并且将应用相同的转换服务将 String 值强制转换为缺失属性的目标类型。
这是从官方文档中获得的更详细的示例:
import java.net.InetAddress;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DefaultValue;
import org.springframework.boot.context.properties.ConstructorBinding;
@ConstructorBinding
@ConfigurationProperties("acme")
public class AcmeProperties {
private final boolean enabled;
private final InetAddress remoteAddress;
private final Security security;
public AcmeProperties(boolean enabled, InetAddress remoteAddress, Security security) {
this.enabled = enabled;
this.remoteAddress = remoteAddress;
this.security = security;
}
public boolean isEnabled() { ... }
public InetAddress getRemoteAddress() { ... }
public Security getSecurity() { ... }
public static class Security {
private final String username;
private final String password;
private final List<String> roles;
public Security(String username, String password,
@DefaultValue("USER") List<String> roles) {
this.username = username;
this.password = password;
this.roles = roles;
}
public String getUsername() { ... }
public String getPassword() { ... }
public List<String> getRoles() { ... }
}
}
Run Code Online (Sandbox Code Playgroud)
尽可能少的样板代码的一种方法是使用仅带有 getter 的接口
public interface AppProps {
String getNeededProperty();
}
Run Code Online (Sandbox Code Playgroud)
并在 Lombok@Getter和@Setter注释的帮助下摆脱实现中的样板 getter 和 setter :
@ConfigurationProperties(prefix = "props")
@Getter
@Setter
public class AppPropsImpl implements AppProps {
private String neededProperty;
}
Run Code Online (Sandbox Code Playgroud)
然后,对于只能通过接口访问其他 bean 的 bean bo,可以考虑将其放入一个配置中,该配置将通过接口公开它,而不是将其标记为@Component或@EnableConfigurationProperties(AppPropsImpl.class)在主应用程序类上使用:
@Configuration
@EnableConfigurationProperties
public class PropsConfiguration {
@Bean
public AppProps appProps(){
return new AppPropsImpl();
}
}
Run Code Online (Sandbox Code Playgroud)
现在这个 bean 只能通过使用接口注入,这使得其他 bean 无法使用 setter:
public class ApplicationLogicBean {
@Autowired
AppProps props;
public void method(){
log.info("Got " + props.getNeededProperty());
}
}
Run Code Online (Sandbox Code Playgroud)
使用 Spring Boot 1.5.3 和 Lombok 1.16.16 进行测试。
开箱即用是不可能的。@ConfigurationPropertiesbeans 必须有标准的 getter 和 setter。您可能需要考虑此答案中描述的方法:Immutable @ConfigurationProperties
或者是这样的:
@Component
public class ApplicationProperties {
private final String property1;
private final String property2;
public ApplicationProperties(
@Value("${some.property1"}) String property1,
@Value("${some.other.property2}) String property2) {
this.property1 = property1;
this.property2 = property1;
}
//
// ... getters only ...
//
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2725 次 |
| 最近记录: |