简介:本文详解SpringBoot项目中域名前缀查询的实现方案,涵盖配置管理、动态解析、安全控制及性能优化,提供可落地的代码示例与最佳实践。
在分布式微服务架构中,域名前缀(如api.、admin.)常用于区分服务类型或环境(测试/生产)。SpringBoot项目通过动态解析域名前缀,可实现以下目标:
test.example.com和prod.example.com区分测试与生产环境。api.example.com或dashboard.example.com路由至不同服务模块。典型场景包括:
client1.example.com)。beta.example.com)。
server:servlet:context-path: /api # 基础路径前缀domain:prefix: admin # 自定义域名前缀
通过@Value("${domain.prefix}")注入前缀值,适用于前缀固定的场景。
@Servicepublic class DomainPrefixService {@Autowiredprivate JdbcTemplate jdbcTemplate;@Cacheable("domainPrefix")public String getPrefixByTenant(String tenantId) {return jdbcTemplate.queryForObject("SELECT prefix FROM domain_config WHERE tenant_id=?",String.class, tenantId);}}
结合Spring Cache实现缓存,减少数据库查询。
启动时通过-Ddomain.prefix=staging覆盖配置,适合容器化部署。
public class DomainPrefixFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;String domain = req.getServerName();String prefix = domain.split("\\.")[0]; // 提取前缀(如"admin")// 将前缀存入ThreadLocal或RequestAttributereq.setAttribute("domainPrefix", prefix);chain.doFilter(request, response);}}
注册Filter:
@Beanpublic FilterRegistrationBean<DomainPrefixFilter> domainPrefixFilter() {FilterRegistrationBean<DomainPrefixFilter> registration = new FilterRegistrationBean<>();registration.setFilter(new DomainPrefixFilter());registration.addUrlPatterns("/*");return registration;}
spring:cloud:gateway:routes:- id: admin_serviceuri: lb://admin-servicepredicates:- Path=/api/**- Header=X-Domain-Prefix, admin # 或通过自定义Predicate解析域名
自定义Predicate示例:
public class DomainPrefixRoutePredicate implements RoutePredicateFactory {@Overridepublic Predicate<ServerWebExchange> apply(Config config) {return exchange -> {String domain = exchange.getRequest().getHeaders().getHost().getHostString();return domain.startsWith(config.getPrefix() + ".");};}}
@Componentpublic class DomainPrefixValidator {private static final Set<String> ALLOWED_PREFIXES = Set.of("api", "admin", "client");public boolean isValid(String prefix) {return ALLOWED_PREFIXES.contains(prefix);}}
^[a-zA-Z0-9-]+$)。
@SpringBootTestpublic class DomainPrefixTest {@Autowiredprivate DomainPrefixService service;@Testpublic void testPrefixParsing() {MockHttpServletRequest request = new MockHttpServletRequest();request.setServerName("admin.example.com");// 通过Filter或直接调用解析逻辑String prefix = service.extractPrefix(request);assertEquals("admin", prefix);}}
@Beanpublic MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {return registry -> registry.config().commonTags("prefix.status", "success/fail");}
对于region.client1.example.com等多级前缀,可采用分层解析:
public class MultiLevelPrefixParser {public Map<String, String> parse(String domain) {String[] parts = domain.split("\\.");Map<String, String> result = new HashMap<>();result.put("region", parts.length > 2 ? parts[0] : "default");result.put("client", parts.length > 1 ? parts[1] : "default");return result;}}
通过以上方案,SpringBoot项目可灵活支持各类域名前缀场景,同时保障安全性与性能。实际开发中需根据业务复杂度选择合适层级,避免过度设计。