1. Giới thiệu
Nhiều nhóm dựa vào các ứng dụng có giá trị và đã được kiểm chứng được xây dựng trên các phiên bản trước của Java và Spring. Mặc dù những ứng dụng này có thể đáp ứng tốt các nhu cầu hiện tại, nhưng việc hiện đại hoá chúng là chìa khoá để truy cập vào các bản vá bảo mật mới nhất, những điểm cải thiện về hiệu suất (chẳng hạn như luồng ảo) và các tính năng mới của ngôn ngữ. Nhiệm vụ này không chỉ dành cho các doanh nghiệp lớn; các nhóm thuộc mọi quy mô đều cần phải áp dụng và hiện đại hoá cơ sở mã để đảm bảo an toàn và hiệu quả. Antigravity, một ứng dụng ưu tiên tác nhân, giúp đẩy nhanh quá trình này bằng cách cung cấp cho nhà phát triển các tác nhân AI tự động có thể suy luận thông qua mã lạ, xác định các phần phụ thuộc và tự động hoá quá trình tái cấu trúc tẻ nhạt.
Trung tâm của Antigravity là Trình quản lý tác nhân, một trang tổng quan "Trung tâm kiểm soát" để tạo, giám sát và tương tác với các tác nhân này khi chúng thực hiện các nhiệm vụ phức tạp. Lớp học lập trình này tập trung vào việc tận dụng Trình quản lý tác nhân để điều phối các tác nhân sẽ hiện đại hoá khối đơn Spring PetClinic từ Spring Boot 2.7 (Java 8/11) thành Spring Boot 4.0.1 và Java 25, cho phép bạn dành ít thời gian hơn để giải mã logic cũ và dành nhiều thời gian hơn để cung cấp các tính năng mới.
Kiến thức bạn sẽ học được
- Giải thích mã cũ bằng Trình quản lý tác nhân.
- Nâng cấp tệp bản dựng Maven lên Spring Boot 4.0.1.
- Tự động hoá quá trình di chuyển không gian tên
javax.*sangjakarta.*. - Tái cấu trúc kho lưu trữ thành các mẫu Spring Data JPA.
- Bật các tính năng hiện đại như Luồng ảo và Actuator.
- Khắc phục và tạo các bài kiểm thử bằng AI.

2. Thiết lập môi trường
- Truy cập vào Antigravity: Bạn sẽ hoàn thành lớp học lập trình này bằng Antigravity, một ứng dụng ưu tiên tác nhân. Bạn sẽ chủ yếu tương tác với Agent Manager, trung tâm kiểm soát tích hợp cho các tác nhân AI.
- Antigravity: Tải ứng dụng ưu tiên tác nhân xuống tại antigravity.google.
- Mở Agent Manager: Khởi chạy Antigravity rồi mở Agent Manager. Đây là giao diện bạn sẽ dùng để tương tác với các tác nhân AI của Antigravity

- Sao chép mẫu: Các lệnh này sẽ sao chép ứng dụng mẫu, thay đổi thành thư mục mới và kiểm tra cam kết cụ thể để ghim ứng dụng vào Spring Boot 2.7.0. Đây là điểm xuất phát cho quá trình hiện đại hoá của chúng ta:
git clone https://github.com/spring-projects/spring-petclinic.git cd spring-petclinic git checkout 1db99dbb58f670ef8e39e9f1edf134b21ce919d6
3. Phân tích mã cũ
Hiểu rõ logic cũ là bước đầu tiên để di chuyển an toàn. Agent Manager có thể giúp bạn hiểu rõ cơ sở mã và tạo lộ trình cho nỗ lực hiện đại hoá của mình. Thay vì đi sâu vào từng tệp ngay lập tức, bạn có thể yêu cầu Trình quản lý tác nhân cung cấp thông tin tổng quan về cơ sở mã để giúp bạn lên kế hoạch cho chiến lược hiện đại hoá.
Ví dụ: bạn có thể yêu cầu Trình quản lý tác nhân:
Give me a tour of this codebase to help plan a modernization strategy. Keep it high-level for now (no need to investigate the codebase line-by-line yet), and please organize your findings using these categories:
The Layout: Map out the main folders and what they do—specifically where the business rules are kept versus the setup and configuration files.
The Traffic Jams: Spot the files that seem to be the 'center of gravity.' These are the classes or modules that many other parts of the app depend on.
The Islands: Identify parts of the code that are relatively isolated. These are the components that have very few connections to the rest of the system and could be moved or updated first.
The Data Path: Trace the lifecycle of a typical request, showing how it moves from the entry point through the logic layer and down to the database.
Write the text summary to migration-map.md, and please include a Mermaid.js class diagram at the bottom that visualizes these relationships for those with a viewer installed.
Agent Manager sẽ cung cấp thông tin tóm tắt về cấu trúc cơ sở mã, xác định các thành phần và phần phụ thuộc chính, đồng thời giúp bạn xác định những ứng viên phù hợp cho các nỗ lực hiện đại hoá ban đầu. Thông tin tổng quan chiến lược này giúp bạn đưa ra quyết định sáng suốt về nơi cần bắt đầu tái cấu trúc.

Sau khi cảm thấy đã nắm vững cơ sở mã hiện tại, bạn có thể chuyển sang bước tiếp theo để bắt đầu quá trình hiện đại hoá.
4. Nâng cấp lên Spring Boot 4.x
1. Cập nhật pom.xml bằng Trình quản lý tác nhân
Yêu cầu Agent Manager cập nhật pom.xml cho Spring Boot 4.0.1 (hoặc phiên bản mới hơn) và Java 25, đồng thời hiện đại hoá các phần phụ thuộc:
Help me update pom.xml to Spring Boot 4.0.1 (or later) and Java 25. Replace mysql-connector-java with mysql-connector-j, add jakarta.xml.bind-api, update jacoco-maven-plugin to 0.8.13, update spring-javaformat-maven-plugin to 0.0.41, ensure spring-boot-starter-cache is used instead of javax.cache, and add modular test starters (webmvc-test, data-jpa-test, restclient).
2. Di chuyển không gian tên
Yêu cầu Agent Manager thực hiện công việc đổi tên gói:
Perform a project-wide migration from javax.* to jakarta.* for persistence, validation, and servlet packages. Also, update CacheConfiguration.java to use the Spring Boot 4.0.1 CacheManagerCustomizer interface.
3. Sửa định dạng và bản dựng
Chạy trình định dạng và thực hiện một bản dựng bỏ qua kiểm thử để xác minh nguồn chính biên dịch:
mvn spring-javaformat:apply
mvn clean package -Dmaven.test.skip=true
5. Hiện đại hoá quyền truy cập dữ liệu
Các kho lưu trữ cũ thường dùng chú thích @Query theo cách thủ công cho các thao tác mà Spring Data hiện đại có thể tự động xử lý.
1. Tái cấu trúc logic (kho lưu trữ)
- Mở
OwnerRepository.java. - Hỏi Người quản lý tác nhân:
Refactor OwnerRepository to extend JpaRepository. Remove redundant findById/save/findAll methods and update others to use Spring Data method naming conventions. ensure findById returns Optional<Owner>. - Agent Manager tái cấu trúc giao diệnTrước:
Sau:public interface OwnerRepository extends Repository<Owner, Integer> { @Query("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id") Owner findById(@Param("id") Integer id); @Query("SELECT DISTINCT owner FROM Owner owner left join owner.pets WHERE owner.lastName LIKE :lastName%") Page<Owner> findByLastName(@Param("lastName") String lastName, Pageable pageable); }// Extends JpaRepository to inherit standard CRUD methods (findById, save, etc.) public interface OwnerRepository extends JpaRepository<Owner, Integer> { // Derived query method - no manual @Query needed! Page<Owner> findByLastNameStartingWith(String lastName, Pageable pageable); }
2. Tái cấu trúc logic (bộ điều khiển)
Nếu OwnerController.java hiển thị lỗi, hãy hỏi Trình quản lý tác nhân:
Fix compiler errors in OwnerController caused by findById returning Optional in modern JpaRepository. Use .orElseThrow() or .orElse(new Owner()) as appropriate.
Trước:
Owner owner = this.owners.findById(ownerId);
Sau:
Owner owner = this.owners.findById(ownerId)
.orElseThrow(() -> new IllegalArgumentException("Invalid ownerId: " + ownerId));
6. Bật các tính năng hiện đại của Java
Spring Boot 4 trên Java 25 cho phép cải thiện đáng kể thông lượng với cấu hình tối thiểu. Để tận dụng các tính năng này, trước tiên, bạn cần đảm bảo rằng bạn đang chạy Java 25.
1. Thiết lập Java 25 bằng SDKMAN
Để chạy ứng dụng bằng Java 25 và sử dụng các công cụ như jcmd để chẩn đoán, bạn cần có JDK Java 25. SDKMAN là một công cụ phổ biến để quản lý các phiên bản song song của nhiều Bộ phát triển phần mềm, bao gồm cả Java.
- Cài đặt SDKMAN: Nếu bạn chưa cài đặt SDKMAN, hãy chạy lệnh sau trong cửa sổ dòng lệnh:
curl -s "https://get.sdkman.io" | bash source "$HOME/.sdkman/bin/sdkman-init.sh" - Cài đặt Java 25: Sau khi cài đặt SDKMAN, hãy cài đặt và kích hoạt Temurin Java 25:
sdk install java 25-tem sdk use java 25-tem
2. Định cấu hình ứng dụng
- Mở
src/main/resources/application.properties. - Hỏi Người quản lý tác nhân:
Expose health and Prometheus endpoints in Actuator, and enable Virtual Threads for request processing. - Áp dụng các thuộc tính được đề xuất:
management.endpoints.web.exposure.include=health,prometheus spring.threads.virtual.enabled=true
Liệu việc này có thực sự mang lại hiệu quả gì không?
Việc bật Luồng ảo sẽ thay thế các luồng hệ điều hành tốn kém bằng các luồng ảo nhẹ do JVM quản lý cho các tác vụ liên kết I/O, giúp cải thiện hiệu suất và khả năng mở rộng. Hãy tạo và chạy ứng dụng để xem các thành phần này hoạt động.
Xác minh rằng các luồng ảo đang được sử dụng
Trước tiên, hãy đảm bảo bạn đã đóng gói ứng dụng (như đã thực hiện ở bước 3 của phần "Nâng cấp lên Spring Boot 4.x"):
mvn clean package -Dmaven.test.skip=true
Tiếp theo, hãy chạy các lệnh sau để khởi động ứng dụng ở chế độ nền, lấy mã nhận dạng tiến trình (PID) của ứng dụng, gửi tải đến ứng dụng bằng Apache Benchmark (ab) và kiểm tra việc sử dụng luồng ảo bằng jcmd.
# Start app in background and wait a few seconds for it to initialize
java -jar target/spring-petclinic-*.jar &
echo "Waiting 15s for app to start..."
sleep 15
# Get PID
PID=$(jps -l | grep spring-petclinic | awk '{print $1}')
echo "App running with PID: $PID"
# Start load generator in background to ensure virtual threads are created
echo "Simulating 100 concurrent users in background..."
ab -n 100 -c 100 http://localhost:8080/owners/find > /dev/null 2>&1 &
# Check for virtual threads under load
echo "Checking for virtual threads with jcmd:"
sleep 5 # wait for load to hit server
jcmd $PID Thread.print | grep VirtualThread
# Clean up
echo "Stopping background load generator and app..."
pkill ab
kill $PID
Nếu các luồng ảo được bật đúng cách, jcmd sẽ xuất dấu vết ngăn xếp luồng bao gồm VirtualThread, xác nhận rằng JVM đang chủ động lập lịch các luồng siêu nhẹ:
"VirtualThread-unblocker" #53 daemon prio=5
...
Thông tin chẩn đoán này xác nhận rằng các luồng ảo đang được dùng để xử lý các yêu cầu. Bây giờ, hãy xem xét tác động đến hiệu suất.
Thiết lập đường cơ sở
Chạy Apache Benchmark để mô phỏng 100 người dùng đồng thời:
ab -n 5000 -c 100 http://localhost:8080/owners/find
- Đầu ra (So sánh):
# Virtual Threads OFF Requests per second: 1047.45 [#/sec] (mean) Time per request: 95.470 [ms] (mean) # Virtual Threads ON Requests per second: 1317.12 [#/sec] (mean) Time per request: 75.923 [ms] (mean) - Kết quả dự kiến: Tăng 25% thông lượng và giảm 20% độ trễ bằng cách loại bỏ chi phí chuyển đổi luồng trong quá trình chặn DB.
Xác minh mức tác động
Chạy lệnh này: Xác minh rằng thời gian chạy đã tải cơ sở hạ tầng lập lịch cần thiết.
jcmd <PID> VM.class_hierarchy | grep VirtualThread
- Đầu ra:
java.lang.VirtualThread jdk.management.VirtualThreadSchedulerMXBean - Kết quả: Xác minh rằng thời gian chạy Java 25 hoàn toàn nhận biết và sử dụng các tính năng của Project Loom.
Tóm tắt: Khi nào nên sử dụng luồng ảo?
Trường hợp | Đề xuất? | Lý do |
I/O / DB | Có | Lợi ích tối đa; các luồng "tạo ra" trong khi chờ đợi. |
Khả năng mở rộng | Có | Xử lý hơn 10.000 yêu cầu đồng thời trên một nút duy nhất. |
CPU Heavy | Không | Sử dụng các luồng nền tảng cho điện toán thô. |
7. (Không bắt buộc) Sửa và tạo các kiểm thử
Việc hiện đại hoá đòi hỏi bạn phải cập nhật các hoạt động kiểm thử để khớp với tên gói, API và các phương pháp hay nhất mới. Đây cũng là thời điểm thích hợp để sử dụng Agent Manager nhằm tạo các kiểm thử mới và cải thiện phạm vi kiểm thử tổng thể.
Khắc phục các kiểm thử cũ
Thư mục src/test có thể gặp lỗi biên dịch do việc đổi tên gói (javax thành jakarta) và các thay đổi về API (các loại trả về Optional trong kho lưu trữ). Yêu cầu Trình quản lý tác nhân khắc phục những vấn đề này trên tất cả các tệp kiểm thử:
Fix compilation errors in src/test. Replace deprecated @MockBean with @MockitoBean. Update test imports for WebMvcTest and DataJpaTest to their new Spring Boot 4 modular tags. Update mocks (like given(owners.findById(...))) to return Optional.of(owner).
Lời nhắc này hướng dẫn Trình quản lý tác nhân thực hiện những việc sau:
- Di chuyển các lệnh nhập kiểm thử sang
jakarta.*. - Thay thế chú giải kiểm thử Spring không dùng nữa bằng các chú giải tương đương hiện đại.
- Cập nhật định nghĩa mô phỏng để phù hợp với các phương thức kho lưu trữ hiện trả về
Optional.
Tạo các kiểm thử mới để cải thiện mức độ phù hợp
Trong quá trình hiện đại hoá, bạn có thể phát hiện ra những điểm thiếu sót trong phạm vi kiểm thử. Agent Manager có thể giúp bạn tạo các bài kiểm thử mới cho các phương thức hoặc lớp cụ thể, để đảm bảo ứng dụng hiện đại hoá của bạn được kiểm thử kỹ lưỡng.
Ví dụ: chọn một phương thức trong OwnerController.java không có đủ quy trình kiểm thử và yêu cầu Trình quản lý tác nhân:
Generate a JUnit 5 test for this method using MockMvc.
Agent Manager sẽ tạo một phương thức kiểm thử mới mà bạn có thể thêm vào OwnerControllerTests.java.
Xác minh bản dựng và chạy kiểm thử
Sau khi sửa các kiểm thử hiện có và tuỳ ý tạo các kiểm thử mới, hãy chạy bộ kiểm thử đầy đủ để đảm bảo mọi thứ đều đạt:
mvn clean test
Danh sách kiểm tra xác minh
Để xác nhận quá trình hiện đại hoá thành công sẽ giúp nhóm của bạn làm việc hiệu quả với cơ sở mã (Java 25 / Spring Boot 4), hãy xác minh những điều sau:
- Thời gian chạy và bản dựng:
pom.xmlmục tiêu.25 pom.xmlgốc là phiên bảnspring-boot-starter-parent4.0.1.build.gradlenhắm đến Java 25 và Spring Boot 4.0.1.
- Tuân thủ Jakarta EE:
- Tìm kiếm
import javax.trên toàn cầu. Thao tác này sẽ trả về 0 kết quả cho các gói duy trì, servlet hoặc xác thực (đã di chuyển sangjakarta.*).
- Tìm kiếm
- Tiêu chuẩn kiểm thử:
- Các kiểm thử sử dụng
@MockitoBeanthay vì@MockBeancũ. - Các lớp kiểm thử nhập
org.junit.jupiter.api.Test(JUnit 5), chứ không phảiorg.junit.Test(JUnit 4). - Các mô phỏng kho lưu trữ trả về
Optional.of(entity)thay vì các thực thể trực tiếp.
- Các kiểm thử sử dụng
8. Các bước tiếp theo
Chúc mừng bạn đã hoàn thành Lớp học lập trình này! Bạn đã tìm hiểu thành công cách sử dụng Agent Manager để hiện đại hoá một ứng dụng Java cũ.
Bạn có thể tham khảo các tài liệu và nội dung khác sau đây để đọc thêm: