Mục lục
Một trong những tính năng cốt lỗi của Spring framework là IoC (Inversion of Control) container. Spring IoC container chịu trách nhiệm quản lý các bean object trong toàn bộ ứng dụng.
Trong bài viết này, chúng ta sẽ cùng nhau về BeanFactory và ApplicationContext là 2 interface sử dụng để thao tác với Spring container.
Bean là gì
Trước tiên, để hiểu rõ ApplicationContext và BeanFactory, chúng ta cần phải hiểu rõ bean là gì?. Trong Spring, bean là một object được Spring container khởi tạo, lắp ráp và sử dụng.
Vì vậy, chúng ta có nên cấu hình tất cả các object trong ứng dụng dưới dạng Spring bean không? Không bên các bạn nhé.
Theo như tài liệu chính thức của Spring, chúng ta chỉ nên định nghĩa các bean cho các service object, data access object (DAO), presentation object và các object dựng nên cơ sở hạ tầng của Spring như Hibernate SessionFactories, JMS Queues, v.v.
Điểm khác nhau giữa BeanFactory và ApplicationContext interface
BeanFactory và ApplicationContext interface là 2 interface đại diện cho Spring IoC container. BeanFactory là root interface dùng để thao tác với Spring container, nó cung cấp những tính năng cơ bản để quản lý bean trong ứng dụng.
ApplicationContext interface là một sub-interface của BeanFactory, vì vậy nó cung cấp tất cả các tính năng trong BeanFactory ngoài ra nó còn cung cấp một số tính năng quan trọng khác như:
- Bean instantiation/wiring
- Automatic BeanPostProcessor registration
- Automatic BeanFactoryPostProcessor registration
- Convenient MessageSource access (for i18n)
- ApplicationEvent publication
Nó sử dụng tính năng eager loading vì vậy tất cả các bean sẽ được khởi tạo sau khi ApplicationContext được khởi động.
Cấu hình Bean trong Spring
Như đã thảo luận ở trên, thì chức năng chính của ApplicationContext là quản lý các bean trong ứng dụng. Vì vậy, một ứng dụng Spring phải cung cấp một hoặc nhiều bean cho Spring container quản lý.
Trong các ứng dụng Spring hiện tại, chúng ta có thể định nghĩa một Bean thông qua 2 annotation là @Component và @Bean annotation khá đơn giản, điểm khác nhau giữa chúng là @Component được dùng để chú thích cho một class trong khi @Bean được dùng để chú thích trên method.
Đầu tiên, chúng ta sẽ đánh dấu Company class với @Component annotation
@Component public class Company { private Address address; public Company(Address address) { this.address = address; } // getter, setter and other properties }
Dưới đây là Config class cung cấp các metadata cho IoC container:
@Configuration @ComponentScan(basePackageClasses = Company.class) public class Config { @Bean public Address getAddress() { return new Address("High Street", 1000); } }
Khi class được đánh dấu với @Configuration nó sẽ được xem là một trong những class cung cấp các thông tin cấu hình cho ứng dụng, vì vậy chúng sẽ được đọc và khởi tạo đầu tiên.
Trong Config class khởi tạo một Bean với kiểu dữ liệu là Address. Ngoài ra nó còn sử dụng @ComponentScan annotation dùng để hướng dẫn cho IoC container tìm kiếm và khởi tạo một Bean mới trong package chứa Company class từ đó nó cũng tạo ra một Bean có kiểu Company.
Khi Spring IoC container khởi tạo các object có kiểu dữ liệu Address và Company chúng được gọi là các Spring Bean được quản lý bởi IoC container. Bất cứ nơi nào cần sử dụng chúng sẽ đều phải yêu cầu đến IoC container và nó sẽ trả về những Bean đã khởi tạo trước đó.
Sử dụng ApplicationContext trong Spring Boot
Để sử dụng ApplicationContext trong Spring Boot, chúng ta chỉ cần autowired vào và sử dụng. Spring sẽ tự động tiêm một dependency application tương ứng.
Gỉa sử mình định nghĩa một MyBean sau
@Component public class MyBean { public String getName() { return "My Bean"; } }
Sau đó, mình có một ApplicationContextService sử dụng ApplicationContext để lấy MyBean object từ Spring container ra sử dụng
@Service public class ApplicationContextService { @Autowired private ApplicationContext applicationContext; public String getMyBeanName() { MyBean myBean = applicationContext.getBean(MyBean.class); return myBean.getName(); } }
Cuối cùng, chúng ta có thể kiểm thử để xem kết quả cuối cùng với junit như sau:
@SpringBootTest class ApplicationContextApplicationTests { @Autowired private ApplicationContextService applicationContextService; @Test void contextLoads() { Assertions.assertEquals(applicationContextService.getMyBeanName(), "My bean"); } }
Sau cùng các bạn có thể xem mã nguồn mình công khai trên gitlab để chạy và kiểm thử nếu cần thiết: application-context.
Nguồn tham khảo
https://dzone.com/articles/difference-between-beanfactory-and-applicationcont