1.6 资源管理最佳实践
1.6.1 多环境资源配置策略(企业级方案)
Profile机制深度解析:
多维度配置方案:
# application.yml(公共配置)
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Drivertype: com.zaxxer.hikari.HikariDataSource---
# 开发环境配置
spring:profiles: devdatasource:url: jdbc:mysql://dev-db:3306/app?useSSL=falseusername: dev_userpassword: dev123hikari:maximum-pool-size: 5---
# 生产环境配置
spring:profiles: proddatasource:url: jdbc:mysql://prod-cluster:3306/app?useSSL=trueusername: ${DB_PROD_USER}password: ${DB_PROD_PASS}hikari:maximum-pool-size: 20connection-timeout: 3000
Profile激活策略:
// 1. 启动参数指定
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication app = new SpringApplication(Application.class);app.setAdditionalProfiles("prod", "azure");app.run(args);}
}// 2. 条件化Bean配置
@Configuration
@Profile("cloud")
public class CloudConfig {@Beanpublic CloudService cloudService() {return new AzureCloudService();}
}// 3. 测试环境专用配置
@TestConfiguration
@Profile("test")
public class MockConfig {@Bean@Primarypublic PaymentService mockPaymentService() {return new MockPaymentService();}
}
1.6.2 加密配置安全处理方案(金融级安全)
Jasypt集成全流程:
<!-- Maven依赖 -->
<dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>3.0.5</version>
</dependency>
// 加密工具类
public class ConfigEncryptor {public static void main(String[] args) {StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();encryptor.setPassword(System.getenv("CONFIG_SECRET"));String plainText = "sensitive_data";String encrypted = encryptor.encrypt(plainText);System.out.println("ENC(" + encrypted + ")");}
}
安全配置实践:
# application-secure.properties
spring.datasource.password=ENC(4Bv7dsf8sKjeiT9sLkja8W2xzlpT4r4T)# 启动参数设置密钥
java -jar app.jar --jasypt.encryptor.password=${CONFIG_SECRET_KEY}
Kubernetes密钥管理方案:
# Kubernetes部署文件
apiVersion: v1
kind: Secret
metadata:name: app-secrets
type: Opaque
data:db-password: NkJ2N2RzZjhzS2plaVQ5c0xramE4VzJ4emxwVDRyNFQKapi-key: VGhpcyBpcyBhIHNlY3JldCBrZXkK
// 动态获取K8s密钥
@Value("${secrets.db-password}")
private String decodedDbPassword;
1.6.3 国际化消息资源高级用法(多语言电商系统)
消息资源配置架构:
resources/
├─ messages/
│ ├─ messages.properties(默认)
│ ├─ messages_en_US.properties
│ ├─ messages_zh_CN.properties
│ └─ messages_ja_JP.properties
└─ application.yml
动态消息加载实现:
@Configuration
public class I18nConfig {@Beanpublic MessageSource messageSource() {ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();messageSource.setBasename("classpath:messages/messages");messageSource.setDefaultEncoding("UTF-8");messageSource.setCacheMillis(5000); // 5秒刷新return messageSource;}@Beanpublic LocalResolver localeResolver() {SessionLocaleResolver resolver = new SessionLocaleResolver();resolver.setDefaultLocale(Locale.ENGLISH);return resolver;}
}// 业务层使用示例
@Service
public class ProductService {private final MessageSource messageSource;public String getLocalizedMessage(String code, Locale locale, Object... args) {return messageSource.getMessage(code, args, locale);}public void showError(HttpServletRequest request) {Locale locale = LocaleContextHolder.getLocale();String message = messageSource.getMessage("error.insufficient_stock", new Object[]{product.getName()}, locale);throw new BusinessException(message);}
}
Thymeleaf多语言集成:
<!-- 前端页面示例 -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title th:text="#{page.title}"></title>
</head>
<body><h1 th:text="#{welcome.message(${user.name})}"></h1><!-- 语言切换 --><div><a th:href="@{/?lang=en}">English</a><a th:href="@{/?lang=zh_CN}">中文</a><a th:href="@{/?lang=ja_JP}">日本語</a></div>
</body>
</html>
动态消息更新方案:
// 消息热更新端点
@RestController
@RequiredArgsConstructor
public class MessageReloadController {private final ReloadableResourceBundleMessageSource messageSource;@PostMapping("/admin/i18n/reload")public ResponseEntity<String> reloadMessages() {messageSource.clearCache();return ResponseEntity.ok("Messages reloaded at " + new Date());}@PostMapping("/admin/i18n/update")public ResponseEntity<String> updateMessage(@RequestParam String code,@RequestParam String value,@RequestParam String lang) throws IOException {String fileName = "messages_" + lang + ".properties";Path filePath = Paths.get("src/main/resources/messages/" + fileName);Properties props = new Properties();try (InputStream in = Files.newInputStream(filePath)) {props.load(in);}props.setProperty(code, value);try (OutputStream out = Files.newOutputStream(filePath)) {props.store(out, "Updated at " + new Date());}return ResponseEntity.ok("Message updated");}
}
1.6.4 资源监控与防护(生产环境必备)
连接池监控配置:
@Configuration
public class DataSourceConfig {@Beanpublic HikariDataSource dataSource() {HikariConfig config = new HikariConfig();config.setJdbcUrl("jdbc:mysql://localhost:3306/app");config.setUsername("root");config.setPassword("securepass");config.setMaximumPoolSize(20);config.setMetricRegistry(Metrics.globalRegistry);return new HikariDataSource(config);}@Beanpublic MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {return registry -> registry.config().commonTags("application", "order-service");}
}
资源防护策略:
@Configuration
public class ResourceProtectionConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {// 静态资源防护registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/").setCachePeriod(3600).resourceChain(true).addResolver(new EncodedResourceResolver()).addTransformer(new CssLinkResourceTransformer());// 敏感文件屏蔽registry.addResourceHandler("/**").addResourceLocations("classpath:/public/").setUseLastModified(true).resourceChain(true).addResolver(new PathResourceResolver() {@Overrideprotected Resource getResource(String resourcePath, Resource location) throws IOException {if (resourcePath.endsWith(".gitignore")) {return null;}return super.getResource(resourcePath, location);}});}
}