Gradle+Spring Boot+Angular9项目:静态文件变更自动重启Spring方案
Great question! Let's get you that smooth ng serve-like experience for your Gradle + Spring Boot + Angular 9 stack, so you don't have to manually run two commands every time you make a change. We'll tie together Angular's watch mode, Gradle task automation, and Spring DevTools to handle auto-recompilation and server restarts/refreshes automatically.
Step 1: Make Sure Spring DevTools is Set Up
First, we need Spring DevTools to detect changes and trigger server restarts or browser refreshes. Add this dependency to your build.gradle:
dependencies { // Only active in development environments developmentOnly 'org.springframework.boot:spring-boot-devtools' }
Then configure DevTools in src/main/resources/application.properties to watch the right paths and enable live reloading (way faster than full server restarts for frontend changes):
# Enable automatic server restarts when backend/resource files change spring.devtools.restart.enabled=true # Watch your Angular source directory to trigger recompilation (paired with Angular watch) spring.devtools.restart.additional-paths=src/main/webapp # Enable LiveReload for browser auto-refreshes (no server restart needed for frontend-only changes) spring.devtools.livereload.enabled=true # Exclude the compiled frontend directory from restart triggers (since Angular watch handles this) spring.devtools.restart.exclude=resources/**/public/**
Step 2: Create Gradle Tasks for Angular Auto-Compilation
We need two key tasks here: one to build Angular once (for server startup), and another to run Angular in watch mode so it auto-recompiles when you edit frontend code.
Add these to your build.gradle:
// Task: Build Angular once (runs on server startup to ensure frontend assets exist) tasks.register('ngBuild') { group = 'frontend' description = 'Builds Angular application once to resources/public' doLast { exec { // Navigate to your Angular source directory workingDir project.file('src/main/webapp') // Compile Angular and output directly to Spring Boot's public resource folder commandLine 'ng', 'build', '--output-path', '../../resources/public' // If you prefer using npm scripts, replace the commandLine with: // commandLine 'npm', 'run', 'build' // (just make sure your package.json has "build": "ng build --output-path=../../resources/public") } } } // Task: Run Angular in watch mode (auto-recompiles on frontend code changes) tasks.register('ngWatch') { group = 'frontend' description = 'Runs Angular build in watch mode to auto-update resources/public' doLast { exec { workingDir project.file('src/main/webapp') // Watch for frontend changes and recompile automatically commandLine 'ng', 'build', '--watch', '--output-path', '../../resources/public' // Again, you can use an npm script here: commandLine 'npm', 'run', 'build:watch' } } } // Combined task: Start Spring Boot with automatic frontend recompilation tasks.register('bootRunWithFrontend') { group = 'application' description = 'Starts Spring Boot server + auto-compiles Angular on code changes' // Run a full Angular build first to ensure assets are ready dependsOn('ngBuild') // Start the Spring Boot server dependsOn('bootRun') // Launch Angular watch mode after the server starts finalizedBy('ngWatch') // Ensure tasks run in the right order without blocking tasks.named('bootRun') { mustRunAfter('ngBuild') } tasks.named('ngWatch') { mustRunAfter('bootRun') } }
Step 3: Run the Combined Task
Now just execute this single command, and you're set:
./gradlew bootRunWithFrontend
What Happens Next:
- First run: Gradle will build your Angular app once, start the Spring Boot server, then launch Angular's watch mode.
- Frontend changes: When you edit files in
src/main/webapp, Angular auto-recompiles and updatesresources/public. DevTools' LiveReload will trigger your browser to refresh instantly (no server restart needed!). - Backend changes: If you modify Java code or backend resources, DevTools will automatically restart the Spring Boot server for you.
Optional: Tie to the Default bootRun Task
If you want to skip typing the long task name every time, you can configure the default bootRun task to include frontend automation:
tasks.named('bootRun') { dependsOn('ngBuild') finalizedBy('ngWatch') }
Now you can just run ./gradlew bootRun and get the same auto-update behavior.
Fixing Your Original Task
Your original bootRunAll task ran ng build once then started the server, but it didn't handle continuous changes. The setup above replaces that with a persistent watch mode that works seamlessly with Spring DevTools.
内容的提问来源于stack exchange,提问作者Fran b

