Spring 引导 - 将所有自动装配的配置变量集中在一个 class

Spring Boot - having all autowired config variables in one class

我正在 Spring Boot 中开发一个微服务,我有一个通用配置 class,我在其中存储了从 application.properties 文件中获得的所有配置变量。它看起来像这样:

Config.java

package programming

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Configuration
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CommonConfiguration {
    
    @Value("${user-pool.id}")
    private String userPoolId;

    @Value("${client.id}")
    private String clientId;
    ...
    ...
    ...
}
 

然后每当我在其他 classes 中需要这些变量时,我会自动装配 Config.java class,并像这样简单地使用它:

@Autowired
private Config config;

public void method1() {
    ...
    String key = items.get(config.getClientId()).toString();
}

有一个通用配置 class 来存储所有自动装配的变量并在需要时在其他 classes 中使用它们是 spring 引导中的一个好习惯吗?如果没有,最好的方法是什么?任何帮助将不胜感激。谢谢!

更好的方法是像这样做一些事情

@ConfigurationProperties(prefix = "optional.key")
Public class MyProperties{
    Int example;
    String example2;
    Getters/setters
}

您现在可以在 application.properties 中键入

optional.key.example=5

您可以在任何需要的地方使用 Autowerire MyProperties

编辑 在maven中加入如下依赖也不错,它会生成一个helper文件,让你的idea可以识别定义的属性

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
</dependency>

重播评论中的问题的小补充 如果您不想使用通用密钥,可以将前缀留空并使用 @ConfigurationProperties 注释 class 可以使用 subclasses 轻松处理子键我将 post 这里是我的一个项目的示例

@ConfigurationProperties(prefix = "swagger")
public class SpringFoxProperties {
    private Info info = new Info();
    private Config config = new Config();

    public Info getInfo() {
        return info;
    }

    public void setInfo(Info info) {
        this.info = info;
    }

    public Config getConfig(){
        return config;
    }

    public void setConfig(Config config) {
        this.config = config;
    }

    public static class Config {
        private String paths = "";
        private String documentationType = "openApi";

        public String getPaths() {
            return paths;
        }

        public void setPaths(String paths) {
            this.paths = paths;
        }

        public String getDocumentationType() {
            return documentationType;
        }

        public void setDocumentationType(String documentationType) {
            this.documentationType = documentationType;
        }
    }

    public static class Info {
        private String title = "";
        private String description = "";
        private String version = "";
        private String termsOfServiceUrl = "";
        private Contact contact = new Contact();
        private License license = new License();

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public String getVersion() {
            return version;
        }

        public void setVersion(String version) {
            this.version = version;
        }

        public String getTermsOfServiceUrl() {
            return termsOfServiceUrl;
        }

        public void setTermsOfServiceUrl(String termsOfServiceUrl) {
            this.termsOfServiceUrl = termsOfServiceUrl;
        }

        public Contact getContact() {
            return contact;
        }

        public void setContact(Contact contact) {
            this.contact = contact;
        }

        public License getLicense() {
            return license;
        }

        public void setLicense(License license) {
            this.license = license;
        }

        public static class Contact {
            private String name  = "";
            private String url  = "";
            private String email  = "";

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public String getUrl() {
                return url;
            }

            public void setUrl(String url) {
                this.url = url;
            }

            public String getEmail() {
                return email;
            }

            public void setEmail(String email) {
                this.email = email;
            }
        }

        public static class License {
            private String name  = "";
            private String url  = "";

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public String getUrl() {
                return url;
            }

            public void setUrl(String url) {
                this.url = url;
            }
        }
    }
} 

示例application.yml

swagger:
  info:
    title: title
    description: description
    version: version
    termsOfServiceUrl: termsOfServiceUrl
    contact:
      name: name
      url: url
      email: email
    license:
      name: name
      url: url
  config:
    paths: /api/.*
    documentation-type: swagger

Would having a common configuration class that stores all the autowired variables and use these when needed in other classes a good practice in spring boot? If not, what would be the best way to go about this? Any help would be greatly appreicated.

我对那部分的回答是:绝对不会!

您正在为所有需要配置的 class 引入一个真正的 class 依赖项。这样一来,您实际上是在逆转 spring 提供的配置注入。

重点是能够在目标 class 的字段中直接注入您需要的配置的特定部分(例如,通过使用 @Value("${foo.bar} " private String fooBar;))

因此您还禁用了特定功能的使用(例如,在不同的 classes 中使用不同的配置文件和 @Profile),我相信还有更多示例表明您实际上限制了灵活性。

我看不出您的方法有任何好处 - 您也可以解释一下为什么需要这种方法:)