Bean và ApplicationContext là gì trong Spring Boot?

1. Bean và ApplicationContext là gì?

1.1. Bean là gì?

Trong documentation của Spring framework, thì bean được định nghĩa như sau:

In Spring, the objects that type the spine of your utility and which can be managed by the Spring IoC container are known as beans. A bean is an object that’s instantiated, assembled, and in any other case managed by a Spring IoC container.

Nói 1 bí quyết đơn giản, bean là những module chính của chương trình, được tạo ra và quản lý bởi Spring IoC container.

Những bean có thể phụ thuộc lẫn nhau, như thí dụ về Automotive, Engine và ChinaEngine từ đầu collection tới giờ. Sự phụ thuộc này được mô tả cho IoC biết nhờ có cơ chế Dependency injection.

Bí quyết đánh dấu class là 1 bean thì mình sẽ trình bày trong bài tiếp theo. Lúc này người sử dụng chỉ cần biết đơn giản nhất là dùng @Element lên class là class đấy là 1 bean.

1.2. ApplicationContext là gì?

ApplicationContext là khái niệm Spring Boot dùng để chỉ Spring IoC container, tương tự động như bean là đại diện cho những dependency.

Bên cạnh ra bạn có thể sẽ nghe nói về BeanFactory. Nó cũng đại loại như ApplicationContext, đại diện cho Spring IoC container nhưng tại mức cơ bản. ApplicationContext thì tại mức cao hơn, phân phối nhiều tính năng hơn BeanFactory như i18n, resolving messages, publishing occasions,…

Lúc ứng dụng Spring chạy, Spring IoC container sẽ quét toàn bộ packages, tìm ra những bean và đưa vào ApplicationContext. Cơ chế đấy là Element scan, cũng sẽ được nói tới trong bài tiếp theo.

Xem Thêm  Bộ tộc là gì?

1.3. Bí quyết lấy bean ra từ Context

Tất nhiên trước lúc lấy bean ra từ context thì bắt buộc có context rồi Câu hỏi đặt ra là biến context tại đâu?

Ấy là ngay dòng khởi đầu chương trình Spring Boot. Câu lệnh sau.

@SpringBootApplication public class Utility { public static void important(String[] args) { sentayho.com.vn(Utility.class, args); } }

Dòng technique sentayho.com.vn() sẽ return về 1 object ApplicationContext interface, đại diện cho IoC container.

ApplicationContext context = sentayho.com.vn(Utility.class, args);

Chúng ta có thể lấy ra bean từ đây, dùng technique getBean().

// Lấy ra bean có class cụ thể Automotive automobile = sentayho.com.vnean(Automotive.class); // Lấy ra theo tên và class // Tuy là sentayho.com.vn nhưng Engine lại là interface Engine engine = sentayho.com.vnean(“ChinaEngine”, sentayho.com.vns);

2. Kĩ thuật inject bean vào bean khác

Thí dụ bạn có 2 bean là Automotive và Engine (như thí dụ từ đầu collection tới giờ). Và Automotive thì phụ thuộc vào Engine, do đấy theo Dependency injection thì chúng ta cần inject Engine vào trong Automotive.

2.1. Dùng @Autowired

Chúng ta dùng annotation @Autowired để báo cho Spring biết tự động động tìm và inject bean thích hợp vào vùng đặt annotation. Thí dụ.

// Annotation chỉ đánh dấu lên class public interface Engine { void run(); } @Element public class ChinaEngine implements Engine { @Override public void run() {} } @Element public class Automotive { // Báo cho Spring tìm bean nào thích hợp có Engine interface // Và có 1 bean thích hợp là ChinaEngine // Nó tương đương có = new ChinaEngine() @Autowired personal closing Engine engine; }

Xem Thêm  Trải nghiệm vẻ đẹp của quốc hoa 1 số quốc gia trên thế giới

Bí quyết dùng @Autowired trên subject là ko được khuyến khích, do nó dùng Java reflection để inject. Chúng ta nên cân nhắc đổi qua dùng inject theo kiểu constructor hoặc setter.

2.2. Inject qua constructor hoặc setter

Code inject theo kiểu constructor-based nên dùng lúc những module là phải}. Lúc đấy Spring Boot lúc tạo bean (cũng chỉ là tạo object, gọi constructor thôi) thì sẽ đưa những phụ thuộc vào constructor lúc gọi.

Thí dụ class Automotive đã được sửa lại để inject Engine vào qua constructor.

@Element public class Automotive { personal closing Engine engine; // Những bản Spring Boot new thì ko cần @Autowired trên constructor public Automotive(Engine engine) { sentayho.com.vn = engine; } }

Hoặc dùng kiểu setter-based như sau. Spring Boot sau thời điểm tạo xong bean Automotive sẽ gọi thêm technique setEngine() tiếp tục.

@Element public class Automotive { personal closing Engine engine; // Thêm @Required để setter luôn được gọi để inject @Required public void setEngine(Engine engine) { sentayho.com.vn = engine; } }

Bí quyết dùng setter để inject thường dùng trong trường hợp phụ thuộc vòng, module A phụ thuộc vào B và ngược lại. Do đấy, trường hợp cả 2 đều dùng constructor based mostly injection thì Spring Boot sẽ ko biết nên tạo bean nào trước. Vì thế, giải pháp là 1 bean sẽ dùng constructor, 1 bean dùng setter như trên.

3. Lúc Spring Boot ko biết chọn bean nào?

3.1. Lúc tìm thấy nhiều bean thích hợp

Cũng lấy thí dụ trên, trường hợp chúng ta tạo thêm class VNEngine có chức năng tương tự động ChinaEngine.

Xem Thêm  CASA, Chỉ số quan yếu nhất ngành nhà băng?

@Element public class VNEngine implements Engine { @Override public void run() {} }

Thì Spring Boot sẽ báo lỗi như sau (báo lúc chạy và cả trong IDE nữa.

Có thể hiểu do Spring Boot đã tìm thấy 2 bean thích hợp để inject vào Automotive. Do cả 2 VNEngine và ChinaEngine đều implements Engine, mà Automotive cần Engine nên ko biết nên chọn loại nào.

3.2. Giải pháp

Có 2 bí quyết giải quyết vấn đề này. Thứ 1 là dùng @Major đánh dấu lên 1 bean. Lúc đấy bean này sẽ được ưu tiên chọn hơn, trong trường hợp có nhiều bean thích hợp trong context.

@Element @Major public class VNEngine implements Engine { … }

Bí quyết 2 là chỉ định rõ tên bean (tên class) cụ thể được inject bằng @Qualifier.

@Element public class Automotive { @Autowired @Qualifier(“VNEngine”) // Buộc phải khớp hoa thường luôn nhe personal closing Engine engine; }

Đối có constructor hay setter based mostly cũng tương tự động, chỉ cần có @Qualifier trước tên subject cần inject vào là được.

Okay thế là bài viết hôm nay đã xong. 2 bài viết về bean và context của mình hello vọng sẽ mang trong mình tới cho người sử dụng đủ những tri thức cơ bản để đi tiếp những phần sau của collection. Cảm ơn và nhớ upvote hoặc clip để ủng hộ mình nhé. Thân!