0

[Java Backend Zero to Hello] [Phase 5] BÀI 5.1: TỔNG QUAN SPRING FRAMEWORK

📚 Series: Java Backend Zero to Hello 📂 Phân đoạn: Phase 5: Spring Framework & Spring Boot 📖 Nội dung: BÀI 5.1: TỔNG QUAN SPRING FRAMEWORK 💡 Khóa học lập trình Backend Java & Spring Boot chuẩn doanh nghiệp từ con số 0.


BÀI 5.1: TỔNG QUAN SPRING FRAMEWORK

Mục tiêu

  • Hiểu Spring Framework và lịch sử
  • Nắm IoC (Inversion of Control) và DI (Dependency Injection)
  • Hiểu Bean và ApplicationContext
  • Tạo project Spring đầu tiên

1. SPRING FRAMEWORK LÀ GÌ?

Spring là framework Java phổ biến nhất cho phát triển ứng dụng enterprise, cung cấp:

  • IoC Container - Quản lý object
  • Dependency Injection - Tiêm phụ thuộc
  • AOP - Lập trình hướng khía cạnh
  • Data Access - JDBC, ORM, Transaction
  • Web MVC - Framework web
  • Security - Bảo mật
  • Boot - Auto-configuration

Spring Ecosystem

Spring Framework (Core)
├── Spring Boot         - Auto-config, embedded server
├── Spring Data         - JPA, MongoDB, Redis
├── Spring Security     - Authentication, Authorization
├── Spring Cloud        - Microservices
├── Spring Batch        - Batch processing
└── Spring Integration  - Enterprise integration

2. IoC - INVERSION OF CONTROL

2.1 Vấn đề

// ❌ Tight coupling - class tự tạo dependency
public class UserService {
    private UserRepository repository = new UserRepositoryImpl();
}

2.2 Giải pháp - IoC

// ✅ Loose coupling - dependency được tiêm vào
public class UserService {
    private final UserRepository repository;

    public UserService(UserRepository repository) {
        this.repository = repository;
    }
}

IoC = Đảo quyền kiểm soát - Container quản lý việc tạo và tiêm dependency thay vì class tự quản lý.


3. DI - DEPENDENCY INJECTION

3.1 Constructor Injection (Khuyến nghị)

@Service
public class UserService {
    private final UserRepository repository;
    private final EmailService emailService;

    @Autowired  // Không bắt buộc nếu chỉ có 1 constructor
    public UserService(UserRepository repository, EmailService emailService) {
        this.repository = repository;
        this.emailService = emailService;
    }
}

3.2 Setter Injection

@Service
public class UserService {
    private UserRepository repository;

    @Autowired
    public void setRepository(UserRepository repository) {
        this.repository = repository;
    }
}

3.3 Field Injection (Không khuyến nghị)

@Service
public class UserService {
    @Autowired
    private UserRepository repository;
}

3.4 So sánh

Constructor Setter Field
Bắt buộc dependency Optional Đơn giản
Immutable Mutable Mutable
Dễ test Khó test hơn Khó test
Khuyến nghị Ít dùng Không khuyến nghị

4. BEAN

Bean là object được quản lý bởi Spring IoC Container.

4.1 Khai báo Bean

Với Annotation

@Component
public class UserService { }

@Service
public class OrderService { }

@Repository
public class UserRepository { }

@Controller
public class UserController { }

@RestController
public class ApiController { }

Với @Configuration + @Bean

@Configuration
public class AppConfig {

    @Bean
    public UserService userService(UserRepository repository) {
        return new UserService(repository);
    }
}

4.2 Bean Scope

Scope Mô tả
singleton 1 instance cho toàn app (mặc định)
prototype Mỗi lần tạo mới
request 1 instance cho mỗi HTTP request
session 1 instance cho mỗi HTTP session
application 1 instance cho ServletContext
@Component
@Scope("prototype")
public class MyPrototypeBean { }

5. APPLICATION CONTEXT

ApplicationContext là container chứa và quản lý các bean.

5.1 Khởi tạo

ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

UserService userService = context.getBean(UserService.class);

5.2 Với Spring Boot

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(Application.class, args);
        UserService userService = context.getBean(UserService.class);
    }
}

6. STEREOTYPE ANNOTATIONS

Annotation Mô tả
@Component Generic Spring component
@Service Business logic
@Repository Data access layer
@Controller Web controller (trả về view)
@RestController REST API controller
@Configuration Cấu hình

7. @Autowired

@Service
public class OrderService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    @Qualifier("emailServiceImpl")
    private EmailService emailService;
}

7.1 @Qualifier - Khi có nhiều implementation

public interface EmailService {
    void send(String to, String message);
}

@Service("emailServiceImpl")
public class EmailServiceImpl implements EmailService { }

@Service("smtpEmailService")
public class SmtpEmailService implements EmailService { }

7.2 @Primary - Đánh dấu ưu tiên

@Service
@Primary
public class EmailServiceImpl implements EmailService { }

8. VÒNG ĐỜI CỦA BEAN

Instantiate → Populate Properties → BeanNameAware → BeanFactoryAware
→ ApplicationContextAware → @PostConstruct → InitializingBean
→ Custom init-method → Bean ready → @PreDestroy → DisposableBean
→ Custom destroy-method

8.1 @PostConstruct và @PreDestroy

@Component
public class MyBean {

    @PostConstruct
    public void init() {
        System.out.println("Bean được khởi tạo");
    }

    @PreDestroy
    public void cleanup() {
        System.out.println("Bean bị hủy");
    }
}

9. PROFILES

Cấu hình khác nhau cho từng môi trường.

@Configuration
@Profile("dev")
public class DevConfig {
    @Bean
    public DataSource dataSource() {
        // H2 in-memory
    }
}

@Configuration
@Profile("prod")
public class ProdConfig {
    @Bean
    public DataSource dataSource() {
        // MySQL production
    }
}

Kích hoạt: --spring.profiles.active=dev


10. VÍ DỤ HOÀN CHỈNH

10.1 Cấu trúc

src/main/java/com/example/
├── Application.java
├── controller/
│   └── UserController.java
├── service/
│   ├── UserService.java
│   └── impl/
│       └── UserServiceImpl.java
├── repository/
│   └── UserRepository.java
└── model/
    └── User.java

10.2 Code

// User.java
public class User {
    private Long id;
    private String name;
    private String email;
    // getters, setters
}

// UserRepository.java
@Repository
public class UserRepository {
    private Map<Long, User> users = new HashMap<>();
    private AtomicLong counter = new AtomicLong();

    public User save(User user) {
        if (user.getId() == null) {
            user.setId(counter.incrementAndGet());
        }
        users.put(user.getId(), user);
        return user;
    }

    public Optional<User> findById(Long id) {
        return Optional.ofNullable(users.get(id));
    }

    public List<User> findAll() {
        return new ArrayList<>(users.values());
    }
}

// UserService.java
public interface UserService {
    User createUser(User user);
    Optional<User> getUser(Long id);
    List<User> getAllUsers();
}

// UserServiceImpl.java
@Service
public class UserServiceImpl implements UserService {
    private final UserRepository repository;

    public UserServiceImpl(UserRepository repository) {
        this.repository = repository;
    }

    @Override
    public User createUser(User user) {
        return repository.save(user);
    }

    @Override
    public Optional<User> getUser(Long id) {
        return repository.findById(id);
    }

    @Override
    public List<User> getAllUsers() {
        return repository.findAll();
    }
}

// UserController.java
@RestController
@RequestMapping("/api/users")
public class UserController {
    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping
    public List<User> getAll() {
        return userService.getAllUsers();
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getById(@PathVariable Long id) {
        return userService.getUser(id)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
    }

    @PostMapping
    public User create(@RequestBody User user) {
        return userService.createUser(user);
    }
}

// Application.java
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

11. BÀI TẬP THỰC HÀNH

Bài 1: Tạo project Spring

Tạo project với:

  • UserController, UserService, UserRepository
  • CRUD cơ bản

Bài 2: Sử dụng các Scope

Tạo bean với scope prototype và singleton, kiểm tra sự khác biệt.

Bài 3: @PostConstruct

Tạo bean in message khi khởi tạo và hủy.


12. TÓM TẮT

Khái niệm Mô tả
IoC Đảo quyền kiểm soát
DI Tiêm phụ thuộc
Bean Object được quản lý bởi Spring
ApplicationContext Container chứa bean
@Component, @Service, @Repository Stereotype annotations
@Autowired Tiêm dependency
@Scope Phạm vi bean
@Profile Cấu hình theo môi trường

Bài tiếp theo: 5.2 Spring Boot cơ bản


🧭 Điều hướng bài học

⭐ Hãy bookmark (clip) lại series để tiện theo dõi các bài học tiếp theo nhé!


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí