首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >系统配置自动装载机制 - 分布式开发

系统配置自动装载机制 - 分布式开发

作者头像
JavaEdge
修改2025-11-17 15:55:05
修改2025-11-17 15:55:05
7470
举报
文章被收录于专栏:JavaEdgeJavaEdge

本文已收录在Github关注我,紧跟本系列专栏文章,咱们下篇再续!

  • 🚀 魔都架构师 | 全网30W技术追随者
  • 🔧 大厂分布式系统/数据中台实战专家
  • 🏆 主导交易系统百万级流量调优 & 车联网平台架构
  • 🧠 AIGC应用开发先行者 | 区块链落地实践者
  • 🌍 以技术驱动创新,我们的征途是改变世界!
  • 👉 实战干货:编程严选网

1 @SpringBootApplication

三个注解的功能集成:

1.1 @EnableAutoConfiguration、@ComponentScan

在应用程序所在的包上启用扫描

代码语言:java
复制
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
       @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

配置组件扫描指令,以与 Configuration 类一起使用。

代码语言:bash
复制
com
   +- javaedge
       +- myapplication
           +- Application.java
           |
           +- customer
           | 		+- Customer.java
           | 		+- CustomerController.java
           | 		+- CustomerService.java
           | 		+- CustomerRepository.java
           |
           +- order
               +- Order.java
               +- OrderController.java
               +- OrderService.java
               +- OrderRepository.java
代码包扫描

默认的包结构及其作用:

  • 主程序Application.java放在根包, 在其他类之上
  • @SpringBootApplication写在主程序上
  • Spring对类的扫描默认仅涵盖主程序所在的包及子包

1.2 @Configuration

允许在Spring中注册额外的bean或导入其他配置类

代码语言:java
复制
// 表明一个类提供 Spring Boot 应用的 @Configuration(即配置类)。它可作为 Spring 标准 @Configuration 注解的替代品,使得该配置能够被自动发现(如在单元测试中)。
// 一个 Spring Boot 应用只能包含 一个 @SpringBootConfiguration,而最常见的做法是让应用通过 @SpringBootApplication 继承它
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration //see!!!
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
    @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
    @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class)
})
public @interface SpringBootApplication {
Spring配置文件

SpringBoot中建议放弃通过XML定义Spring应用程序,推荐在代码类上面通过@Configuration实现配置。如有需要,还可通过@ImportResource导入xml配置文件。

2 个性化依赖配置

类别

注解

说明

条件依赖

@ConditionalOnClass

应用中包含某个类时,对应的配置才生效

@ConditionalOnMissingClass

应用中不包含某个类时

@ConditionalOnBean

Spring容器中存在指定class的实例对象时

@ConditionalOnMissingBean

Spring容器中不存在指定class的实例对象时

@ConditionalOnProperty

指定参数的值符合要求时

@ConditionalOnResource

指定文件资源存在时

@ConditionalOnWebApplication

当前处于Web环境时(WebApplicationContext)

@ConditionalOnNotWebApplication

当前非处于Web环境时,对应的配置才生效。

@ConditionalOnExpression

指定参数的值符合要求时,对应的配置才生效。 和ConditionalOnProperty的区别在于这个注解使用Spring EL表达式。

先后顺序

@AutoConfigureAfter

指定Configuration类后加载。

@AutoConfigureBefore

指定Configuration类前加载。

@AutoConfigureOrder

指定该Configuration类的加载顺序,默认值0

3 外部参数配置信息加载

Spring应用可通过属性文件,YAML文件,环境变量和命令行参数等方式的外部化参数配置

启动时命令行传参

代码语言:bash
复制
java -jar app.jar --name="test"

SpringBoot配置信息中的特殊值

代码语言:bash
复制
SPRING_ APPLICATION_ JSON='{"name'":"test"}'

如果是web应用,可读取ServletConfig init参数。

JNDI属性

来自java:comp/env

4 Java系统属性

代码语言:java
复制
System.getProperties()

user.dir

Java系统属性之一,表示当前用户的工作目录(working directory),也称当前工作路径(current working directory)。当Java应用程序启动时,会自动设置这个属性的值,指向该应用所在的目录。

user.dir指Java程序运行时的当前目录路径,而非Java文件所在的目录路径:

  • 若Java应用程序是通过命令行执行的,就是运行命令的进程的当前工作目录
  • 若是在IDE中运行,就是项目的根目录
代码语言:java
复制
System.getProperty("user.dir")

代码语言:java
复制
System.getenv().forEach((k, v) -> {
    System.out.println(k + ":" + v);
});

COMMAND_MODE:unix2003
LC_CTYPE:zh_CN.UTF-8
RABBIT_HOME:/usr/local/Cellar/rabbitmq/3.12.1
JAVA_HOME:/Users/javaedge/Library/Java/JavaVirtualMachines/openjdk-22.0.1/Contents/Home
HOMEBREW_BOTTLE_DOMAIN:https://mirrors.ustc.edu.cn/homebrew-bottles/bottles
SHELL:/bin/zsh
TMPDIR:/var/folders/lh/hztrg5y17w50q03jvnqyy2pw0000gn/T/
__CFBundleIdentifier:com.jetbrains.intellij
HOME:/Users/javaedge
SSH_AUTH_SOCK:/private/tmp/com.apple.launchd.FmZOzahGyn/Listeners
OLDPWD:/
XPC_SERVICE_NAME:application.com.jetbrains.intellij.91501400.94811146
PATH:/Users/javaedge/Downloads/PycharmProjects/google-cloud-sdk/bin:/usr/local/opt/krb5/sbin:/usr/local/opt/krb5/bin:/usr/local/opt/ffmpeg@5/bin:/Users/javaedge/Library/Java/JavaVirtualMachines/openjdk-22.0.1/Contents/Home/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/VMware Fusion.app/Contents/Public:/Library/Apple/usr/bin:/Users/javaedge/Library/Application Support/org.dfinity.dfx/bin:/Users/javaedge/Downloads/flutter/bin:/usr/local/Cellar/rabbitmq/3.12.1/sbin:/Users/javaedge/Downloads/soft/apache-maven-3.9.6/bin
M2_HOME:/Users/javaedge/Downloads/soft/apache-maven-3.9.6
WORKON_HOME:/Users/javaedge/virtualenvwrapper_envs
LOGNAME:javaedge
USER:javaedge
HOMEBREW_GITHUB_API_TOKEN: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
__CF_USER_TEXT_ENCODING:0x1F5:0x19:0x34
XPC_FLAGS:0x0
VIRTUALENVWRAPPER_PYTHON:/usr/local/bin/python3
VIRTUALENVWRAPPER_VIRTUALENV:/usr/local/bin/virtualenv
PWD:/Users/javaedge/Downloads/IDEAProjects/education-microservice
HOMEBREW_API_DOMAIN:https://mirrors.ustc.edu.cn/homebrew-bottles/api

获取user.dir属性的值。通常,user.dir被用于:

  • 指定相对路径(如读取资源文件等)
  • 或记录日志文件(如定义日志输出路径等)

总之,user.dir是Java系统属性中一个非常重要的参数,与Java程序的文件操作、路径处理和日志记录等方面密切相关。熟练掌握user.dir属性的使用方法和特性,对于Java开发人员来说是必不可少的基础知识。

os环境变量

配置文件:

  • application.properties
  • application.yml
  • application-{profile.properties、 application-{profile}.yml

@PropertySource

提供一种方便的声明性机制,用于将一个 PropertySource 添加到 Spring 的 Environment,与 @Configuration 类协作。

示例

给定一个app.properties,以下@Configuration类用于@PropertySource贡献 app.properties Environment的集合PropertySources。testbean.name=myTestBean

代码语言:java
复制
@Configuration
@PropertySource("classpath:/com/myco/app.properties")
public class AppConfig {

    @Autowired
    Environment env;

    @Bean
    public TestBean testBean() {
        TestBean testBean = new TestBean();
        testBean.setName(env.getProperty("testbean.name"));
        return testBean;
    }
}

该 Environment 对象位于 @Autowired 配置类,然后在填充 TestBean 对象时使用。给定上述配置,调用 将 testBean.getName() 返回 “myTestBean”。

代码语言:java
复制
解析 ${...} 占 <bean> 位符和 @Value 批注

为了使用 中的PropertySource属性解析定义或@Value注释中的 <bean> ${...}占位符,须确保在 中使用的 ApplicationContext中注册BeanFactory了适当的嵌入值解析程序。在 XML 中使用时,<context:property-placeholder>这会自动发生。使用@Configuration类时,可以通过显式注册 via PropertySourcesPlaceholderConfigurer static @Bean 方法来实现这一点。但请注意,通常只有在需要自定义配置(如占位符语法等)时才需要显式注册 via PropertySourcesPlaceholderConfigurer static @Bean 方法。有关详细信息和示例,请参阅 的 javadocs 的 “使用 外部化值” 部分和 的 @Configuration“BeanFactoryPostProcessor-return @Bean 方法说明”。@Bean

解析资源位置中的 @PropertySource ${...} 占位符

资源位置中@PropertySource存在的任何 ${...} 占位符都将针对已针对环境注册的属性源集进行解析。例如:

代码语言:java
复制
@Configuration
@PropertySource("classpath:/com/${my.placeholder:default/path}/app.properties")
public class AppConfig {

    @Autowired
    Environment env;

    @Bean
    public TestBean testBean() {
        TestBean testBean = new TestBean();
        testBean.setName(env.getProperty("testbean.name"));
        return testBean;
    }
}

假设“my.placeholder”存在于已注册的属性源之一(例如,系统属性或环境变量)中,则占位符将被解析为相应的值。如果没有,则“默认/路径”将用作默认值。表示默认值(由冒号“:”分隔)是可选的。如果未指定默认值且无法解析属性,则会抛出 将 IllegalArgumentException 。

关于属性覆盖的说明 @PropertySource

如果给定的属性键存在于多个 .properties 文件中,则最后 @PropertySource 处理的批注将“获胜”并覆盖具有相同名称的任何先前键。

如给定两个属性文件 a.properties、b.properties,考虑以下两个使用@PropertySource注解它们的配置类:

代码语言:java
复制
@Configuration
@PropertySource("classpath:/com/myco/a.properties")
public class ConfigA {
  
}

@Configuration
@PropertySource("classpath:/com/myco/b.properties")
public class ConfigB {
  
}

重写顺序取决于这些类在应用程序上下文中注册的顺序。

代码语言:java
复制
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ConfigA.class);
ctx.register(ConfigB.class);
ctx.refresh();

上述方案中的 b.properties 属性将覆盖 中 a.properties存在的重复项。

某些情况下,使用 @PropertySource 时严格控制属性源排序可能是不可能或不切实际的。如上面这类是通过组件扫描注册,则 @Configuration 很难预测顺序。这时若重写很重要,建议用户回退到使用编程式 PropertySource API。

根据Java 8,此注解可重复。 但所有这些 @PropertySource 都要在同一级别声明:直接在配置类或作为同一自定义注解上的元注解声明。不建议混合使用直接注释和元注释,因为直接注释将有效地覆盖元注释。

注解导入的配置:

代码语言:java
复制
@Component
@Data
@PropertySource("classpath:tencentCloud.properties")
@ConfigurationProperties(prefix = "tencent.cloud")
public class TencentCloudProperties {

    private String SecretId;

    private String SecretKey;

}

程序入口通过SpringApplication.setDefaultProperties方法设定的参数配置。

5 配置文件

配置文件可以存放在哪些位置?

1.当前项目运行的盘符/config文件夹下面: file../config/

2.当前项目运行的目录下面(命令执行的所在目录) :file:./

  1. classpath 下面的config文件夹: classpath:/config
  2. classpath的根目录(我们平常就是用这种) : classpath:/ 上述配置文件按优先级排列,排在上面的位置会覆盖优先级降低的配置。

6 配置文件格式

SpringBoot支持两种配置文件的格式: .properites、 .yml

yaml语法精简版说明

代码语言:yaml
复制
spring:
  datasoure:
    username: test
list:
  - one
  - two
  • 大小写敏感
  • 使用空格缩进表示层级(不要用TAB),同一层级的左侧对齐
  • map键值对通过“:” 分隔
  • list列表元素通过“”表示

properties示例

代码语言:properties
复制
spring.datasource.username=test

7 参数使用

7.1 @Value

通过 @Value("${my.name}"',将指定的参数配置注入到属性。

7.2 Environment

注入Environment对象。

代码语言:java
复制
// 注入env対象
@Autowired
Environment environment;

// 使用示例
environment.getProperty("name");

7.3 ConfigurationProperties

代码语言:java
复制
@ConfigurationProperties(prefix="my")

将该注解添加到指定的 Java 类上,Spring Boot 会自动将配置文件中以 my 为前缀的属性绑定到该类的对应字段上。

属性需有getters和setters方法。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/12/01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 @SpringBootApplication
    • 1.1 @EnableAutoConfiguration、@ComponentScan
      • 代码包扫描
    • 1.2 @Configuration
      • Spring配置文件
  • 2 个性化依赖配置
  • 3 外部参数配置信息加载
    • 启动时命令行传参
    • SpringBoot配置信息中的特殊值
    • JNDI属性
  • 4 Java系统属性
    • user.dir
    • @PropertySource
      • 示例
  • 5 配置文件
    • 配置文件可以存放在哪些位置?
  • 6 配置文件格式
    • yaml语法精简版说明
    • properties示例
  • 7 参数使用
    • 7.1 @Value
    • 7.2 Environment
    • 7.3 ConfigurationProperties
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档