Spring Boot 将 Java 注释上的配置属性/消息外部化

Posted

技术标签:

【中文标题】Spring Boot 将 Java 注释上的配置属性/消息外部化【英文标题】:Spring boot externalize config properties/messages on Java annotations 【发布时间】:2016-12-30 15:36:54 【问题描述】:

有没有办法在 spring 中从外部属性文件中读取文本而不使用 @Value 注释。例如:application.properties

var.foo="hello"

我可以使用

将它注入到 spring bean 中
@Value("$var.foo") String value;

作为类变量。有没有办法在不使用 @Value 注释的情况下包含此属性。类似于 JSR bean 验证的方式。

@NotNull(message=custom.notnull)

并且您在 ValidationMessages.properties 文件中将该属性值外部化。

例如,如果我有一个资源(Web 组件)类,并且我必须使用 Swagger 注释来记录它们,

@controller
@path("/")
@Api(description = "User Resource API")
public class UserResource 

    @Path("/users")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "returns user details", notes = "some notes")
    public User getUser() 

        return new User(123, "Joe", "Montana");
    

和模型,

@ApiModel("user model")
public class User 

    @ApiModelProperty(value = "This represents user id")
    private String id;
    private String firstName;
    private String lastName;
    ...

如何将此字符串/句子/消息外部化到外部属性文件。我认为这适用于一般的 Java 注释和 spring,而不是特定于 Swagger。我指定 Swagger 的原因是,如果就像休眠验证 Java 库可以选择在外部 ValidationMessages.properties 文件中指定这些消息,并且 spring 知道默认情况下会选择它(或者可以配置)。

Swagger 是否提供这样的选项?如果没有,我该如何设置?

根本问题是,我不想让我的代码/逻辑与文档相关数据(元数据)混为一谈。

【问题讨论】:

您需要提供有关您的用例的更多详细信息,说明您为什么不能或不想使用@Value 注释。 Spring 的另一个领域围绕 i18n 支持,它使用 messages.properties 允许某些领域利用特定语言文本的标记替换。 嗨@shawn.. 感谢您的回复。让我编辑这个问题 【参考方案1】:

我认为你无法实现这一点,除非你使用的注解的底层实现带有他们自己的 i18n 标准(如 ValidationMessages.properties),或者支持 Spring 的 MessageSource

在后一种选择的情况下,您所要做的就是将您的键/值对添加到 messages.properties 文件中,然后让框架完成其余的工作:

messages.properties

my.validation.error.message=Something went terribly wrong!

SomeClass.java

@MySpringCompatibleValidationAnnotation("my.validation.error.message")
private String someVariable;

底线是,根据您尝试使用的框架,它可能支持也可能不支持这种开箱即用的功能。

现在,就 Swagger 而言,i18n 对文档的支持被​​提议作为一项新功能,但在他们对如何实现它进行了更多思考时,它被关闭或搁置了。详情请见https://github.com/OAI/OpenAPI-Specification/issues/274。

【讨论】:

感谢 Thomas 的回复。我觉得 Swagger 注释没有外部化各种注释属性的值会给代码(模型、资源......)增加太多混乱。【参考方案2】:

使用@Value("$property")注解注入配置属性有时会很麻烦,所以spring boot引入了@ConfigurationProperties,这应该是你想要的解决方案。

Here 是参考文档。

【讨论】:

【参考方案3】:

您可以在配置文件中声明 bean 时使用占位符。这里您可以尝试一个示例: https://www.mkyong.com/spring/spring-propertyplaceholderconfigurer-example/

【讨论】:

【参考方案4】:

如果你使用的是Spring Boot那么你可以试试这个方法,不需要做任何特殊配置

@environment.getProperty('property')

【讨论】:

以上是关于Spring Boot 将 Java 注释上的配置属性/消息外部化的主要内容,如果未能解决你的问题,请参考以下文章

将多个 Shiro Realms 集成到 Spring Boot 环境中 Java

Spring Boot Hibernate 自动配置与手动注释配置

如何在 Spring Boot 中使用注释配置视图解析器? [复制]

重新运行 Spring Boot 配置注释处理器以更新生成的元数据

如何根据 Spring Boot 中的活动配置文件设置注释属性值?

控制器方法中 requestBody 上的 Spring Boot @Valid 不起作用