Eclipse老用户迁移指南:用Gradle+Boot打造高效Spring Boot工作流
如果你是从Eclipse时代走过来的Java开发者,可能还记得那些手动管理JAR包的日子——下载依赖、配置classpath、解决版本冲突,每一步都充满挑战。如今,Gradle和Spring Boot的组合已经彻底改变了Java项目的构建方式。本文将带你从Eclipse的传统工作流平滑过渡到现代Gradle构建体系,特别针对Spring Boot项目进行深度优化。
1. 为什么Eclipse开发者需要拥抱Gradle
Eclipse曾经是Java开发的主流IDE,其内置的Ant和后来的Maven支持为一代开发者所熟悉。但Gradle带来了几个革命性的改进:
- 声明式依赖管理:不再需要像Maven那样编写冗长的XML配置
- 增量构建:只重新编译变更的部分,大幅提升构建速度
- 灵活的DSL:Groovy/Kotlin脚本比XML更易读易写
- Spring Boot深度集成:官方推荐的构建工具,提供专属插件
对于Spring Boot项目,Gradle的优势尤为明显。下面是一个传统Maven pom.xml与Gradle build.gradle的对比:
| 功能 | Maven (pom.xml) | Gradle (build.gradle) |
|---|---|---|
| 声明Spring Boot依赖 | 需要parent POM | 只需一个插件声明 |
| 自定义任务 | 需配置插件 | 原生支持Groovy/Kotlin脚本 |
| 构建速度 | 较慢 | 增量构建快2-3倍 |
| 多模块项目 | 可行但配置复杂 | 简洁直观的DSL |
提示:Eclipse的Buildship插件已经相当成熟,完全支持Gradle 7.x及以上版本,不用担心IDE兼容性问题。
2. 环境准备:Eclipse+Gradle完美组合
2.1 安装Buildship插件
虽然新版Eclipse已内置Gradle支持,但建议通过Marketplace安装最新版Buildship:
- 打开Eclipse,进入
Help > Eclipse Marketplace - 搜索"Buildship",选择Gradle官方插件
- 完成安装后重启Eclipse
验证安装成功:
# 在终端检查Gradle版本 gradle -v2.2 配置Gradle运行时
Eclipse默认使用包装器(Wrapper),但建议配置本地Gradle实例:
- 进入
Window > Preferences > Gradle - 选择"Local installation directory"指向你的Gradle安装路径
- 勾选"Offline mode"避免不必要的网络请求
推荐配置:
- Gradle 7.5+版本
- Java 11或17运行环境
- 至少2GB堆内存(在gradle.properties中配置)
3. 从零创建Spring Boot项目
3.1 项目初始化
抛弃传统的向导式创建,改用Gradle的init命令:
# 在终端执行(无需Eclipse) gradle init --type java-application --dsl groovy --test-framework junit-jupiter然后在Eclipse中导入:
File > Import > Gradle > Existing Gradle Project- 选择刚才创建的目录
- 勾选"Buildship"下的所有选项
3.2 关键build.gradle配置
以下是针对Spring Boot 2.7优化的build.gradle示例:
plugins { id 'java' id 'eclipse' id 'org.springframework.boot' version '2.7.3' id 'io.spring.dependency-management' version '1.0.13.RELEASE' } sourceCompatibility = '17' repositories { mavenCentral() maven { url 'https://repo.spring.io/milestone' } } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' runtimeOnly 'com.h2database:h2' // 开发时有用工具 developmentOnly 'org.springframework.boot:spring-boot-devtools' // 测试相关 testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' } test { useJUnitPlatform() } bootRun { // 配置开发时系统属性 systemProperties = System.properties }几个关键点说明:
io.spring.dependency-management插件自动处理Spring生态的版本兼容developmentOnly配置确保devtools不会打包到生产环境bootRun自定义配置方便开发时调试
4. 高效开发工作流
4.1 实时类重载配置
结合Spring Boot DevTools和Eclipse自动构建:
- 在Eclipse中开启自动构建:
Preferences > General > Workspace > Build automatically - 添加DevTools依赖(见上节build.gradle)
- 配置application.properties:
spring.devtools.restart.enabled=true spring.devtools.livereload.enabled=true
注意:修改静态资源时按Ctrl+F9触发快速重启,Java类修改会自动触发
4.2 调试技巧
Gradle项目在Eclipse中的调试需要特殊配置:
- 创建调试配置:
- 右键项目 > Debug As > Debug Configurations
- 创建新的"Gradle Project"配置
- 添加JVM参数:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 - 使用远程调试连接:
Right-click project > Debug As > Remote Java Application
4.3 多模块项目结构
大型项目推荐采用多模块结构,示例settings.gradle:
rootProject.name = 'my-enterprise-app' include 'core-service' include 'web-interface' include 'batch-processor'每个子模块有自己的build.gradle,父项目配置公共部分:
// 根build.gradle subprojects { apply plugin: 'java' apply plugin: 'io.spring.dependency-management' repositories { mavenCentral() } dependencies { implementation platform('org.springframework.boot:spring-boot-dependencies:2.7.3') } }5. 生产环境准备
5.1 构建优化配置
在gradle.properties中添加:
# 并行构建 org.gradle.parallel=true # 守护进程 org.gradle.daemon=true # 缓存配置 org.gradle.caching=true5.2 打包部署
Spring Boot特有的打包方式:
# 生成可执行JAR gradle bootJar # 生成Docker镜像(需Docker插件) gradle bootBuildImage对于War包部署:
// build.gradle添加 apply plugin: 'war' bootWar { archiveFileName = 'app.war' // 排除内嵌容器(如需部署到外部Tomcat) providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat' }5.3 常用Gradle命令速查
| 命令 | 作用 | 常用参数 |
|---|---|---|
| gradle build | 执行完整构建 | --continuous 持续构建 |
| gradle bootRun | 运行Spring Boot应用 | --args='--server.port=8081' |
| gradle test | 运行测试 | --tests *ServiceTest |
| gradle dependencies | 显示依赖树 | --configuration runtimeClasspath |
| gradle clean build | 清理后重新构建 | -x test 跳过测试 |
6. 疑难问题解决
6.1 常见错误处理
依赖冲突:
# 查看依赖树 gradle dependencies # 排除特定依赖 implementation('org.springframework.boot:spring-boot-starter-web') { exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat' }构建缓存问题:
# 清理缓存 gradle clean --refresh-dependencies6.2 性能调优
如果构建速度慢,尝试:
- 增加Gradle堆内存:
# gradle.properties org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g - 启用构建扫描:
gradle build --scan - 避免不必要的任务:
# 只编译不测试不打包 gradle compileJava
7. 进阶技巧
7.1 自定义任务
在build.gradle中添加实用任务:
task openSwaggerUi(type: Exec) { commandLine 'open', 'http://localhost:8080/swagger-ui.html' dependsOn bootRun doFirst { println "启动Swagger UI..." } }7.2 代码生成集成
整合OpenAPI生成器:
plugins { id 'org.openapi.generator' version '5.4.0' } openApiGenerate { generatorName = "spring" inputSpec = "$rootDir/src/main/resources/api-spec.yaml" outputDir = "$buildDir/generated" apiPackage = "com.example.api" modelPackage = "com.example.model" configOptions = [ interfaceOnly: "true", useTags: "true" ] } // 将生成的代码加入源码集 sourceSets.main.java.srcDir "$buildDir/generated/src/main/java"7.3 多环境配置
使用Profiles管理不同环境:
bootRun { // 默认开发环境 systemProperty 'spring.profiles.active', 'dev' } task prodBootRun(type: org.springframework.boot.gradle.tasks.run.BootRun) { systemProperty 'spring.profiles.active', 'prod' }对应application-prod.properties:
spring.datasource.url=jdbc:mysql://prod-db:3306/app spring.jpa.hibernate.ddl-auto=validate8. 从Maven迁移指南
8.1 迁移步骤
- 在项目根目录运行:
gradle init --type pom - 检查生成的build.gradle
- 逐步替换Maven特有配置
8.2 重要概念对比
| Maven概念 | Gradle等效 | 说明 |
|---|---|---|
<dependencies> | dependencies {} | 声明方式更简洁 |
<profiles> | 自定义任务+系统属性 | 更灵活的配置方式 |
<plugins> | plugins {} | 插件DSL更类型安全 |
<properties> | ext {} 或 gradle.properties | 支持更复杂的变量逻辑 |
8.3 迁移检查清单
- [ ] 确保所有依赖在Gradle中都有对应版本
- [ ] 转换Maven插件功能到Gradle任务
- [ ] 配置等效的构建生命周期
- [ ] 设置CI/CD管道使用Gradle命令
- [ ] 更新开发者文档中的构建说明
9. 生态系统整合
9.1 静态代码分析
集成Checkstyle和PMD:
plugins { id 'checkstyle' id 'pmd' } checkstyle { toolVersion = '9.3' configFile = file("${rootDir}/config/checkstyle.xml") } pmd { toolVersion = '6.46.0' ruleSets = [] ruleSetFiles = files("${rootDir}/config/pmd-ruleset.xml") }9.2 数据库迁移
使用Flyway或Liquibase:
dependencies { implementation 'org.flywaydb:flyway-core' // 或 implementation 'org.liquibase:liquibase-core' }配置示例:
spring.flyway.locations=classpath:db/migration spring.flyway.baseline-on-migrate=true9.3 监控与度量
集成Micrometer和Prometheus:
dependencies { implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'io.micrometer:micrometer-registry-prometheus' }10. 持续集成配置
10.1 GitHub Actions示例
name: Java CI with Gradle on: [push, pull_request] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up JDK 17 uses: actions/setup-java@v3 with: java-version: '17' distribution: 'temurin' cache: 'gradle' - name: Build with Gradle run: ./gradlew build - name: Run tests run: ./gradlew test10.2 构建缓存配置
在settings.gradle中:
buildCache { local { directory = new File(rootDir, 'build-cache') removeUnusedEntriesAfterDays = 30 } }11. 开发者体验优化
11.1 预提交钩子
在.git/hooks/pre-commit中添加:
#!/bin/sh ./gradlew check if [ $? -ne 0 ]; then echo "构建检查失败,请修复问题后再提交" exit 1 fi11.2 IDE配置同步
在build.gradle中添加:
eclipse { classpath { downloadSources = true downloadJavadoc = true } }11.3 文档生成
集成Asciidoctor生成API文档:
plugins { id 'org.asciidoctor.jvm.convert' version '3.3.2' } ext { snippetsDir = file('build/generated-snippets') } test { outputs.dir snippetsDir } asciidoctor { inputs.dir snippetsDir dependsOn test }12. 微服务特别配置
12.1 Spring Cloud集成
plugins { id 'org.springframework.cloud.contract' version '3.1.5' } ext { set('springCloudVersion', "2021.0.3") } dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" } } dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-config' implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' }12.2 OpenFeign客户端
dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-openfeign' }创建Feign客户端:
@FeignClient(name = "inventory-service") public interface InventoryClient { @GetMapping("/api/inventory/{sku}") InventoryStatus checkStock(@PathVariable String sku); }13. 响应式编程支持
13.1 WebFlux配置
dependencies { implementation 'org.springframework.boot:spring-boot-starter-webflux' }13.2 R2DBC数据库
dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-r2dbc' runtimeOnly 'io.r2dbc:r2dbc-h2' }响应式Repository示例:
public interface UserRepository extends ReactiveCrudRepository<User, Long> { Flux<User> findByStatus(String status); }14. 安全配置最佳实践
14.1 Spring Security集成
dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' }14.2 JWT支持
dependencies { implementation 'io.jsonwebtoken:jjwt-api:0.11.5' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' }安全配置示例:
@EnableWebSecurity public class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .csrf().disable() .authorizeRequests(auth -> auth .antMatchers("/api/public/**").permitAll() .anyRequest().authenticated() ) .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt); return http.build(); } }15. 测试策略
15.1 分层测试配置
dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'io.projectreactor:reactor-test' testImplementation 'org.springframework.security:spring-security-test' // 集成测试专用配置 testImplementation 'org.testcontainers:junit-jupiter:1.17.3' testImplementation 'org.testcontainers:postgresql:1.17.3' }15.2 测试切片示例
@WebMvcTest(UserController.class) class UserControllerTests { @Autowired MockMvc mvc; @MockBean UserService service; @Test void shouldReturnUser() throws Exception { given(service.findById(any())).willReturn(new User("test")); mvc.perform(get("/api/users/1")) .andExpect(status().isOk()) .andExpect(jsonPath("$.name").value("test")); } }16. 容器化部署
16.1 Docker镜像构建
plugins { id 'org.springframework.boot' version '2.7.3' id 'io.spring.dependency-management' version '1.0.13.RELEASE' id 'com.palantir.docker' version '0.34.0' } docker { name "${project.name}:${project.version}" files bootJar.archiveFile.get() buildArgs(['JAR_FILE': "${bootJar.archiveFileName.get()}"]) }对应的Dockerfile:
FROM eclipse-temurin:17-jre ARG JAR_FILE COPY ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","/app.jar"]16.2 Kubernetes部署
创建deployment.yaml:
apiVersion: apps/v1 kind: Deployment metadata: name: spring-app spec: replicas: 3 selector: matchLabels: app: spring-app template: metadata: labels: app: spring-app spec: containers: - name: app image: your-registry/spring-app:1.0.0 ports: - containerPort: 8080 env: - name: SPRING_PROFILES_ACTIVE value: "prod"17. 性能监控
17.1 Micrometer配置
dependencies { implementation 'io.micrometer:micrometer-core' implementation 'io.micrometer:micrometer-registry-prometheus' }17.2 自定义指标
@RestController public class MetricsController { private final Counter visitCounter; public MetricsController(MeterRegistry registry) { visitCounter = registry.counter("app.visits"); } @GetMapping("/visit") public String visit() { visitCounter.increment(); return "Visited!"; } }18. 日志管理
18.1 Logback配置
在src/main/resources/logback-spring.xml中:
<configuration> <include resource="org/springframework/boot/logging/logback/defaults.xml"/> <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/spring.log}"/> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_FILE}</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz</fileNamePattern> <maxFileSize>10MB</maxFileSize> <maxHistory>30</maxHistory> </rollingPolicy> <encoder> <pattern>${FILE_LOG_PATTERN}</pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="FILE"/> </root> </configuration>18.2 结构化日志
添加Logstash编码器:
dependencies { implementation 'net.logstash.logback:logstash-logback-encoder:7.2' }19. 异常处理策略
19.1 全局异常处理
@RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(ResourceNotFoundException.class) public ResponseEntity<ErrorResponse> handleNotFound(ResourceNotFoundException ex) { return ResponseEntity .status(HttpStatus.NOT_FOUND) .body(new ErrorResponse("NOT_FOUND", ex.getMessage())); } record ErrorResponse(String code, String message) {} }19.2 错误页面配置
# application.properties server.error.whitelabel.enabled=false server.error.path=/error自定义错误控制器:
@RestController @RequestMapping("/error") public class CustomErrorController implements ErrorController { @RequestMapping public ResponseEntity<ErrorResponse> handleError(HttpServletRequest request) { HttpStatus status = getStatus(request); return ResponseEntity .status(status) .body(new ErrorResponse(status.name(), "Something went wrong")); } private HttpStatus getStatus(HttpServletRequest request) { Integer code = (Integer) request.getAttribute("javax.servlet.error.status_code"); return code != null ? HttpStatus.valueOf(code) : HttpStatus.INTERNAL_SERVER_ERROR; } }20. 现代化前端集成
20.1 Thymeleaf配置
dependencies { implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' }20.2 前端构建集成
plugins { id 'com.github.node-gradle.node' version '3.3.0' } node { version = '16.14.2' download = true } task npmBuild(type: NpmTask) { args = ['run', 'build'] } processResources.dependsOn npmBuild21. 消息队列集成
21.1 RabbitMQ配置
dependencies { implementation 'org.springframework.boot:spring-boot-starter-amqp' }21.2 Kafka配置
dependencies { implementation 'org.springframework.kafka:spring-kafka' }消费者示例:
@KafkaListener(topics = "orders") public void processOrder(Order order) { log.info("Processing order: {}", order.getId()); orderService.process(order); }22. 分布式缓存
22.1 Redis配置
dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-redis' }22.2 缓存注解使用
@Service public class ProductService { @Cacheable(value = "products", key = "#id") public Product findById(Long id) { // 数据库查询 } @CacheEvict(value = "products", key = "#product.id") public void update(Product product) { // 更新操作 } }23. 分布式追踪
23.1 Sleuth + Zipkin
dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-sleuth' implementation 'org.springframework.cloud:spring-cloud-sleuth-zipkin' }配置示例:
spring.zipkin.base-url=http://localhost:9411 spring.sleuth.sampler.probability=1.024. API文档生成
24.1 SpringDoc OpenAPI
dependencies { implementation 'org.springdoc:springdoc-openapi-ui:1.6.11' }配置示例:
springdoc.api-docs.path=/api-docs springdoc.swagger-ui.path=/swagger-ui.html25. 数据库迁移策略
25.1 Flyway配置
dependencies { implementation 'org.flywaydb:flyway-core' }25.2 多数据源支持
@Configuration @EnableJpaRepositories( basePackages = "com.example.primary", entityManagerFactoryRef = "primaryEntityManager", transactionManagerRef = "primaryTransactionManager" ) public class PrimaryDataSourceConfig { @Bean @Primary @ConfigurationProperties("spring.datasource.primary") public DataSourceProperties primaryDataSourceProperties() { return new DataSourceProperties(); } @Bean @Primary public DataSource primaryDataSource() { return primaryDataSourceProperties() .initializeDataSourceBuilder() .build(); } }26. 批处理作业
26.1 Spring Batch配置
dependencies { implementation 'org.springframework.boot:spring-boot-starter-batch' }26.2 简单批处理示例
@Configuration public class BatchConfig { @Bean public Job importUserJob(JobRepository jobRepository, Step step) { return new JobBuilder("importUserJob", jobRepository) .start(step) .build(); } @Bean public Step step(JobRepository jobRepository, PlatformTransactionManager txManager) { return new StepBuilder("step", jobRepository) .<User, User>chunk(10, txManager) .reader(reader()) .processor(processor()) .writer(writer()) .build(); } }27. 定时任务
27.1 Scheduled注解
@Service public class ReportService { @Scheduled(cron = "0 0 9 * * MON-FRI") public void generateDailyReport() { // 生成报告逻辑 } }27.2 动态调度
@Configuration @EnableScheduling public class SchedulerConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.addTriggerTask( () -> System.out.println("Dynamic task running"), triggerContext -> { // 动态计算下次执行时间 return new CronTrigger("0 */5 * * * *").nextExecutionTime(triggerContext); } ); } }28. 验证与数据绑定
28.1 Bean验证
dependencies { implementation 'org.springframework.boot:spring-boot-starter-validation' }28.2 自定义验证器
public class UniqueUsernameValidator implements ConstraintValidator<UniqueUsername, String> { private final UserRepository repository; public boolean isValid(String username, ConstraintValidatorContext context) { return !repository.existsByUsername(username); } }29. 国际化支持
29.1 消息源配置
# application.properties spring.messages.basename=messages spring.messages.encoding=UTF-829.2 控制器中使用
@RestController public class GreetingController { @GetMapping("/greet") public String greet(@RequestHeader("Accept-Language") String lang, Locale locale) { return messageSource.getMessage("greeting.message", null, locale); } }30. 安全审计
30.1 Spring Data审计
@EntityListeners(AuditingEntityListener.class) @Entity public class User { @CreatedBy private String createdBy; @LastModifiedDate private LocalDateTime lastModified; }30.2 启用审计
@Configuration @EnableJpaAuditing public class AuditConfig { @Bean public AuditorAware<String> auditorAware() { return () -> Optional.of(SecurityContextHolder.getContext()) .map(SecurityContext::getAuthentication) .filter(Authentication::isAuthenticated) .map(Authentication::getName); } }31. 文件上传处理
31.1 上传配置
# application.properties spring.servlet.multipart.max-file-size=10MB spring.servlet.multipart.max-request-size=10MB31.2 控制器处理
@PostMapping("/upload") public String handleUpload(@RequestParam("file") MultipartFile file) { if (!file.isEmpty()) { Path path = Paths.get("/uploads/" + file.getOriginalFilename()); Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING); return "Upload successful"; } return "Upload failed"; }32. 邮件发送
32.1 邮件配置
# application.properties spring.mail.host=smtp.example.com spring.mail.port=587 spring.mail.username=user spring.mail.password=pass spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true32.2 发送邮件
@Service public class EmailService { private final JavaMailSender mailSender; public void sendSimpleMessage(String to, String subject, String text) { SimpleMailMessage message = new SimpleMailMessage(); message.setTo(to); message.setSubject(subject); message.setText(text); mailSender.send(message); } }33. 健康检查
33.1 自定义健康指标
@Component public class DatabaseHealthIndicator implements HealthIndicator { private final DataSource dataSource; @Override public Health health() { try (Connection conn = dataSource.getConnection()) { return Health.up().withDetail("database", "Available").build(); } catch (Exception e) { return Health.down().withDetail("database", "Unavailable").build(); } } }33.2 健康端点配置
# application.properties management.endpoint.health.show-details=always management.endpoint.health.show-components=always34. 配置管理
34.1 外部化配置
# application.properties app.name=My Application app.description=${app.name} is a Spring Boot application34.2 类型安全配置
@ConfigurationProperties("app") public class AppProperties { private String name; private String description; // getters and setters }35. 自定义启动器
35.1 创建自动配置
@Configuration @ConditionalOnClass(MyService.class) @EnableConfigurationProperties(MyProperties.class) public class MyAutoConfiguration { @Bean @ConditionalOnMissingBean public MyService myService(MyProperties properties) { return new MyService(properties); } }35.2 注册自动配置
在src/main/resources/META-INF/spring.factories中:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.example.MyAutoConfiguration36. 性能优化技巧
36.1 JVM调优
# application.properties spring.main.lazy-initialization=true36.2 连接池配置
# application.properties spring.datasource.hikari.maximum-pool-size=10 spring.datasource.hikari.connection-timeout=3000037. 异常监控
37.1 Sentry集成
dependencies { implementation 'io.sentry:sentry-spring-boot-starter:6.4.1' }37.2 配置Sentry
# application.properties sentry.dsn=https://your-key@sentry.io/your-project sentry.environment=production38. 数据库优化
38.1 JPA调优
# application.properties spring.jpa.properties.hibernate.jdbc.batch_size=20 spring.jpa.properties.hibernate.order_inserts=true38.2 查询优化
public interface UserRepository extends JpaRepository<User, Long> { @EntityGraph(attributePaths = "roles") @Query("select u from User u where u.username = :username") Optional<User> findByUsernameWithRoles(@Param("username") String username); }39. 测试数据准备
39.1 Testcontainers配置
dependencies { testImplementation 'org.testcontainers:junit-jupiter:1.17.3' testImplementation 'org.testcontainers:postgresql:1.17.3' }39.2 集成测试示例
@Testcontainers @DataJpaTest @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) class UserRepositoryTests { @Container static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:14"); @DynamicPropertySource static void configureProperties(DynamicPropertyRegistry registry) { registry.add("spring.datasource.url", postgres::getJdbcUrl); registry.add("spring.datasource.username", postgres::getUsername); registry.add("spring.datasource.password", postgres::getPassword); } }40. 构建信息暴露
40.1 生成构建信息
在build.gradle中添加:
springBoot { buildInfo() }40.2 访问构建信息
# application.properties management.info.build.enabled=true通过/actuator/info端点访问:
{ "build": { "version": "1.0.0", "artifact": "demo", "name": "demo", "group": "com.example", "time": "2023-05-01T10:15:30Z" } }41. 自定义端点
41.1 创建管理端点
@Endpoint(id = "features") @Component public class FeaturesEndpoint { @ReadOperation public Map<String, Object> features() { return Map.of( "featureA", true, "featureB", false ); } }41.2 端点安全配置
# application.properties management.endpoints.web.exposure.include=health,info,features management.endpoint.features.enabled=true42. 配置加密
42.1 Jasypt集成
dependencies { implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.4' }42.2 加密配置
# application.properties jasypt.encryptor.password=my-secret-key