当前位置: 首页 > ops >正文

【Java后端】Spring Boot 全局域名替换

写一个 Spring Boot 全局域名替换 Demo,可以直接跑起来验证。


📂 项目结构

springboot-global-domain-demo├── src/main/java/com/example/demo│    ├── DemoApplication.java│    ├── config/AppProperties.java│    └── controller/TestController.java└── src/main/resources└── application.yml

⚙️ 配置文件 application.yml

server:port: 8081app:base-domain: https://api.example.comservices:user: ${app.base-domain}/userorder: ${app.base-domain}/order

🛠️ 配置类 AppProperties.java

package com.example.demo.config;import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;import java.util.Map;@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {private String baseDomain;private Map<String, String> services;public String getBaseDomain() {return baseDomain;}public void setBaseDomain(String baseDomain) {this.baseDomain = baseDomain;}public Map<String, String> getServices() {return services;}public void setServices(Map<String, String> services) {this.services = services;}
}

🌐 控制器 TestController.java

package com.example.demo.controller;import com.example.demo.config.AppProperties;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class TestController {private final AppProperties appProperties;public TestController(AppProperties appProperties) {this.appProperties = appProperties;}@GetMapping("/test")public String test() {String userUrl = appProperties.getServices().get("user");String orderUrl = appProperties.getServices().get("order");return "User API: " + userUrl + " | Order API: " + orderUrl;}
}

🚀 启动类 DemoApplication.java

package com.example.demo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}

🔍 运行结果

启动应用后访问:

http://localhost:8081/test

返回结果:

User API: https://api.example.com/user | Order API: https://api.example.com/order

这样你只需要在 application.yml 改一处:

app.base-domain=https://api.newdomain.com

所有地方就会自动替换。


那么问题来了?现在这样使用的话,全局每个Controller类里都需要注入这个AppProperties,不优雅。

如果每个 Controller 都要用 AppProperties,那就意味着每个类都要注入一遍。这样虽然符合 Spring 的依赖注入设计,但确实会有点麻烦。

有几种 只需要注入一次,全局就能用 的做法👇:


✅ 方案一:静态常量 + @PostConstruct

AppProperties 初始化时,把值放到静态变量里,所有类直接静态调用。

@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {private String baseDomain;public String getBaseDomain() {return baseDomain;}public void setBaseDomain(String baseDomain) {this.baseDomain = baseDomain;}// 静态变量,供全局调用public static String BASE_DOMAIN;@PostConstructpublic void init() {BASE_DOMAIN = baseDomain;}
}

使用:

String url = AppProperties.BASE_DOMAIN + "/user";

👉 好处:所有类都能直接访问,不需要注入。
👉 缺点:静态变量属于硬编码,测试/Mock 不方便。


✅ 方案二:封装成工具类(推荐一点)

新建一个工具类,注入一次配置,然后全局静态访问。

@Component
public class DomainHolder {private static String baseDomain;@Value("${app.base-domain}")public void setBaseDomain(String baseDomain) {DomainHolder.baseDomain = baseDomain;}public static String getBaseDomain() {return baseDomain;}
}

使用:

String url = DomainHolder.getBaseDomain() + "/order";

✅ 方案三:利用 Spring 的 Environment

Spring Boot 本身有个 Environment,可以随时取配置:

@Autowired
private Environment env;public void test() {String baseDomain = env.getProperty("app.base-domain");System.out.println(baseDomain);
}

如果不想每个地方都注入,可以同样封装成静态工具类:

@Component
public class EnvUtils {private static Environment environment;@Autowiredpublic void setEnvironment(Environment env) {EnvUtils.environment = env;}public static String get(String key) {return environment.getProperty(key);}
}

使用:

String url = EnvUtils.get("app.base-domain") + "/user";

⚡ 总结

  • 如果配置只在少量地方用:直接注入 AppProperties 更优雅。
  • 如果几乎所有 Controller 都要用:推荐 方案二(DomainHolder 工具类),写法简洁,还支持占位符。
  • 如果想最大灵活:用 Environment 封装成工具类。

要不要我帮你写一个 方案二的完整 Demo,这样所有 Controller 里就不用再注入了?

http://www.xdnf.cn/news/19356.html

相关文章:

  • TCP实现线程池竞争任务
  • FPGA|Quartus II 中使用TCL文件进行引脚一键分配
  • 深入理解零拷贝:本地IO与网络IO的性能优化利器
  • Docker基本介绍
  • MySQL 慢查询 debug:索引没生效的三重陷阱
  • 深度学习框架与工具使用心得:从入门到实战优化
  • 动作指令活体检测通过动态交互验证真实活人,保障安全
  • 数字后端tap cell:新老工艺tap cell区别
  • 软考中级数据库系统工程师学习专篇(67、数据库恢复)
  • Linux网络socket套接字(中)
  • AI人工智能大模型应用如何落地
  • DriveDreamer-2
  • C++ 模板全览:从“非特化”到“全特化 / 偏特化”的完整原理与区别
  • CUDA与图形API的深度互操作:解锁GPU硬件接口的真正潜力
  • Linux 系统都有哪些
  • Playwright Python 教程:实战篇
  • docker中的命令(四)
  • Coze源码分析-工作空间-项目开发-前端源码
  • 如何重置SVN被保存的用户名和密码
  • 【pve】
  • 轻量化注意力+脉冲机制,Transformer在低功耗AI中再度进化
  • 吴恩达机器学习作业十 PCA主成分分析
  • 基于单片机智能大棚/温室大棚/智慧农业/智能栽培种植系统/温湿度控制
  • LeetCode 37.解数独
  • k8s三阶段项目
  • 狂神说--Nginx--通俗易懂
  • 线程池八股文
  • 从零开始写个deer-flow-mvp-第一天
  • 拆分TypeScript项目的学习收获:处理编译缓存和包缓存,引用本地项目,使用相对路径
  • 粗糙表面接触模型MATLAB代码