Bài 9: Spring Boot Auto Configuration
1. Cơ chế Auto Configuration trong Spring Boot
Auto Configuration là một trong những tính năng mạnh mẽ và tiện lợi nhất của Spring Boot, giúp đơn giản hóa việc cấu hình ứng dụng bằng cách tự động cấu hình các bean cần thiết dựa trên các dependency có trong classpath. Spring Boot tự động cấu hình các thành phần phổ biến và cung cấp các cấu hình mặc định, giúp giảm thiểu sự cần thiết phải viết nhiều mã cấu hình thủ công.
1.1. Nguyên lý hoạt động của Auto Configuration
Spring Boot sử dụng các lớp auto-configuration được định nghĩa trong các file META-INF/spring.factories để tự động cấu hình các thành phần. Khi ứng dụng khởi động, Spring Boot sẽ kiểm tra các dependency có trong classpath và kích hoạt các cấu hình phù hợp. Điều này được thực hiện bởi lớp SpringFactoriesLoader và các annotation như @ConditionalOnClass, @ConditionalOnMissingBean, @ConditionalOnProperty.
Ví dụ, nếu có dependency spring-boot-starter-web trong classpath, Spring Boot sẽ tự động cấu hình một DispatcherServlet và một embedded server như Tomcat.
1.2. Các annotation phổ biến trong Auto Configuration
@EnableAutoConfiguration: Annotation này được sử dụng trong lớp cấu hình chính để kích hoạt tính năng auto-configuration.
@SpringBootApplication: Annotation này là một tổ hợp của
@EnableAutoConfiguration,@ComponentScan, và@Configuration.@ConditionalOnClass: Annotation này cho phép cấu hình chỉ khi một lớp cụ thể có trong classpath.
@ConditionalOnMissingBean: Annotation này cho phép cấu hình chỉ khi không có bean cụ thể nào được định nghĩa trong context.
@ConditionalOnProperty: Annotation này cho phép cấu hình chỉ khi một thuộc tính cụ thể có giá trị nhất định trong file cấu hình.
2. Cách tùy chỉnh Auto Configuration
Mặc dù auto-configuration rất tiện lợi, đôi khi bạn cần tùy chỉnh hoặc vô hiệu hóa một số cấu hình mặc định để phù hợp với yêu cầu cụ thể của ứng dụng. Spring Boot cung cấp nhiều cách để tùy chỉnh auto-configuration.
2.1. Vô hiệu hóa Auto Configuration
Bạn có thể vô hiệu hóa một hoặc nhiều auto-configuration bằng cách sử dụng annotation @EnableAutoConfiguration hoặc @SpringBootApplication.
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Bạn cũng có thể vô hiệu hóa auto-configuration bằng cách sử dụng thuộc tính trong file application.properties.
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
2.2. Cấu hình lại các bean mặc định
Bạn có thể cấu hình lại các bean mặc định bằng cách định nghĩa lại chúng trong context của ứng dụng. Ví dụ, nếu bạn muốn cấu hình lại DataSource bean, bạn có thể làm như sau:
@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
DataSourceBuilder<?> dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.url("jdbc:mysql://localhost:3306/mydb");
dataSourceBuilder.username("root");
dataSourceBuilder.password("root");
return dataSourceBuilder.build();
}
}
2.3. Sử dụng thuộc tính cấu hình
Spring Boot cho phép tùy chỉnh các cấu hình mặc định thông qua các thuộc tính trong file application.properties hoặc application.yml.
Ví dụ, để cấu hình lại DataSource, bạn có thể sử dụng các thuộc tính sau trong application.properties:
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
3. Ví dụ về Auto Configuration
Dưới đây là một ví dụ về việc sử dụng và tùy chỉnh auto-configuration trong Spring Boot.
3.1. Tạo dự án Spring Boot
Bạn có thể tạo một dự án Spring Boot mới bằng Spring Initializr với các dependency sau:
Spring Web
Spring Data JPA
MySQL Driver
3.2. Cấu trúc dự án
myapp
|-- src
| |-- main
| | |-- java
| | | `-- com
| | | `-- example
| | | `-- myapp
| | | |-- MyApplication.java
| | | `-- config
| | | `-- DataSourceConfig.java
| | | `-- entity
| | | `-- User.java
| | | `-- repository
| | | `-- UserRepository.java
| | | `-- service
| | | `-- UserService.java
| | | `-- controller
| | | `-- UserController.java
| | `-- resources
| | `-- application.properties
|-- pom.xml
3.3. Cấu hình DataSource
// DataSourceConfig.java
package com.example.myapp.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.jdbc.DataSourceBuilder;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
return DataSourceBuilder.create()
.url("jdbc:mysql://localhost:3306/mydb")
.username("root")
.password("root")
.driverClassName("com.mysql.cj.jdbc.Driver")
.build();
}
}
3.4. Entity và Repository
// User.java
package com.example.myapp.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// getters and setters
}
// UserRepository.java
package com.example.myapp.repository;
import com.example.myapp.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
3.5. Service và Controller
// UserService.java
package com.example.myapp.service;
import com.example.myapp.entity.User;
import com.example.myapp.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> findAll() {
return userRepository.findAll();
}
}
// UserController.java
package com.example.myapp.controller;
import com.example.myapp.entity.User;
import com.example.myapp.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public List<User> getAllUsers() {
return userService.findAll();
}
}
3.6. Cấu hình application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
3.7. Chạy ứng dụng
Chạy ứng dụng bằng cách sử dụng Maven:
mvn spring-boot:run
Truy cập URL http://localhost:8080/api/users để xem danh sách người dùng.
4. Kết luận
Trong bài viết này, chúng ta đã tìm hiểu về cơ chế Auto Configuration trong Spring Boot và cách tùy chỉnh nó để phù hợp với nhu cầu cụ thể của ứng dụng. Spring Boot Auto Configuration giúp đơn giản hóa việc cấu hình các thành phần của ứng dụng, giảm thiểu mã cấu hình thủ công và tăng năng suất lập trình. Bằng cách hiểu và tùy chỉnh auto-configuration, bạn có thể tận dụng tối đa các tính năng của Spring Boot để xây dựng các ứng dụng mạnh mẽ và linh hoạt.
Trong bài viết tiếp theo, chúng ta sẽ tìm hiểu về Spring Boot Actuator, một công cụ mạnh mẽ giúp theo dõi và quản lý ứng dụng một cách dễ dàng.