Bài viết Câu hỏi About RongvangIT
profile Pic
0
0

Đăng ngày:

 

Sửa ngày:

140 Lượt xem

@Autowired trong Java Spring

annotationJavaSpring

Xin chào anh em.
Lần này, chúng ta sẽ tìm hiểu về các loại injection sử dụng chú thích (annotation) @Autowired trong Framework Spring.
Bài viết này dành cho những người có kiến thức về Java nhưng mới bắt đầu làm quen với Framework Spring.
Vì tôi cũng là người mới học, nếu bạn có điểm nào cần chỉnh sửa thì hãy đưa ra ý kiến của bạn nhé!

Về @Autowired, nó là cái gì thế?

Nói một cách đơn giản, đây là chú thích (annotation) giúp tạo ra một instance của lớp (class) mà bạn muốn sử dụng. Bằng cách viết chú thích, bạn có thể loại bỏ toán tử new trong lớp và thực hiện việc tạo một instance chỉ trong một lần.

public class HogeClass{

@Autowired
private HugaService hugaService;

...
}

Chỉ cần viết như vậy là bạn có thể gọi phương thức xử lý của HugaService trong lớp này. Tuy nhiên, lưu ý rằng chỉ những lớp đã được đăng ký trong DI Container mà Spring Framework cung cấp mới có thể giao việc tạo instance cho @Autowired.
Để đăng ký vào DI Container, bạn có thể sử dụng các chú thích (annotation) như @Component,@Controller,@Service,@Repository.
※ Vì điều về Dependency Injection không phải là chủ đề chính của bài viết này, nên sẽ không mở rộng nhiều.

Các loại Injection bằng @Autowired

Bây giờ chúng ta sẽ xem xét các loại injection bằng @Autowired.
Có ba cách viết injection như sau:

    • Field Injection (không được khuyến nghị)
    • Setter Injection
    • Constructor Injection (được khuyến nghị)

Chúng ta sẽ xem xét cách viết của mỗi loại.

Field Injection

public class HogeClass{

@Autowired
private HugaService hugaService;
private HugaHugaService hugahugaService;

...
}

Như bạn thấy, đây là cách viết đã được giới thiệu ở trên. Có lẽ vì nó là cách đơn giản nhất trong ba cách, nên nó được sử dụng phổ biến. Tuy nhiên, đây là cách viết được không khuyến nghị trong Spring, hãy chú ý.
※ Lý do được giải thích ở phần khuyến nghị Constructor Injection sau đây.

Setter Injection

public class HogeClass{

private final HugaService hugaService;
private final HugaHugaService hugaHugaService;

@Autowired
public setHugaService(HugaService hugaService){
    this.hugaService = hugaService;
}

@Autowired
public setHugaHugaService(HugaHugaService hugaHugaService){
    this.hugaHugaService = hugaHugaService;
}

...
}

Đây là cách định nghĩa setter cho cấu hình bean và đánh dấu @Autowired. Mặc dù không có quy định rõ ràng về việc nên sử dụng hay không, do tính chất của setter, khả năng thay đổi giá trị sau khi gọi constructor (vì vậy nó có thể được coi là không ổn định) khiến nó ít được sử dụng hơn so với các phương pháp khác…

Constructor Injection

public class HogeClass{

private final HugaService hugaService;
private final HugaHugaService hugahugaService;

@Autowired
public HogeClass(HugaService hugaService){
    this.hugaService = hugaService;
    this.hugahugaService = hugahugaService;
}

...
}

Constructor Injection được khuyến khích sử dụng trong Spring. So với Field Injection, cách viết có vẻ phức tạp hơn một chút và có lẽ bạn sẽ thắc mắc tại sao không sử dụng cách đơn giản hơn? Chúng ta sẽ giải thích điều này sau đây.

Tại sao Constructor Injection được khuyến nghị

Vậy tại sao Constructor Injection được khuyến nghị? Nếu viết ít hơn mà vẫn dễ hiểu, thì Field Injection không phải là lựa chọn tốt sao? Điều này có thể khiến một số người tự hỏi.

Có nhiều lý do mà Constructor Injection được khuyến nghị, nhưng cá nhân tôi nghĩ có ba lý do quan trọng nhất như sau.

Nguyên tắc trách nhiệm đơn lẻ

Trong thiết kế hướng đối tượng, có một nguyên tắc thiết kế được gọi là “Nguyên tắc SOLID”. Nguyên tắc trách nhiệm đơn lẻ là một trong những nguyên tắc được đề xuất trong “Nguyên tắc SOLID”, nói một cách đơn giản là “Một lớp chỉ nên có một trách nhiệm (chức năng) duy nhất”.

Khi Constructor Injection cảm thấy phức tạp (dường như có nhiều lời viện), ít nhất đó là lớp đó đang “chịu trách nhiệm nhiều chức năng (chức năng)” vì nó đang “chịu trách nhiệm nhiều chức năng (chức năng)”.

Nói cách khác, từ quan điểm của Nguyên tắc SOLID, lớp như trên “đang chịu trách nhiệm nhiều chức năng (chức năng)” và do đó làm đối với nguyên tắc.

Bằng cách sử dụng Constructor Injection, bạn có thể dễ dàng nhận ra điều này.

Constructor có thể có tính không biến

Bằng cách thực hiện Constructor Injection, bạn có thể khai báo final cho các trường. Điều này có nghĩa là bạn có thể tạo ra một đối tượng không thể thay đổi (không thể thay đổi trạng thái), hoặc giữ cho một số phụ thuộc chỉ có thể thay đổi được một cách cần thiết. Trong trường hợp của Field Injection, bạn không thể khai báo final, vì vậy mối quan hệ phụ thuộc có thể thay đổi.

Ngăn chặn sự phụ thuộc lặp

Khi sử dụng Constructor Injection với khai báo final, nếu có sự phụ thuộc lặp, cảnh báo sẽ xuất hiện khi ứng dụng bắt đầu. Điều này giúp ngăn chặn sự phụ thuộc lặp và bạn có thể nhận ra sự cảnh báo này khi khởi động ứng dụng. Đối với hai loại Injection khác, không thể phát hiện vấn đề này cho đến khi DI Container của mục tiêu được gọi.

Kết luận

Trên đây chúng ta đã cùng tìm hiểu về @Autowired trong Java Spring rồi. Bản thân tôi đã viết bằng Field Injection vì nó dễ dàng, nhưng sau khi biết về lý do nó không được khuyến khích, tôi đã bắt đầu sử dụng Constructor Injection gần đây. Bạn nên suy nghĩ về ý nghĩa khi sử dụng, vì mọi thứ thuận tiện đều có phần thiếu sót!

dev_pro_it
Đang làm IT tại Japan

Bình luận

Bài viết chưa có bình luận. Hãy trở thành người bình luận đầu tiên!
Sign up for free and join this conversation.
Sign Up
If you already have a RongvangIT account Login
Danh sách thư mục
Bắt đầu ngay với RồngVàngIT - nền tảng chia sẻ kiến thức lập trình tuyệt vời cho kỹ sư Việt Nam!

Hãy đăng nhập để sử dụng hàng loạt các chức năng tuyệt vời của RồngVàngIT !

  1. 1. Bạn sẽ nhận được các bài viết phù hợp bằng chức năng theo dõi tag và người dùng.
  2. 2. Bạn có thể đọc lại các thông tin hữu ích bằng chức năng lưu trữ nội dung.
  3. 3. Chia sẻ kiến thức, đặt câu hỏi và ghi lại quá trình trưởng thành của mình cùng RồngVàngIT !
Tạo tài khoản Đăng nhập
profile Pic