BeanFactory và ApplicationContext trong Spring

Trong các bài viết của mình về Spring framework, mình thường sử dụng đối tượng của interface ApplicationContext như là một Spring container để gọi đến đối tượng mình cần lấy. Ví dụ như ở bài trước:

Nhưng thật ra Spring còn hỗ trợ cho chúng ta một interface khác mà đối tượng hiện thực nó cũng là Spring container, tên là BeanFactory.

Nên nếu bây giờ bạn thay thế ApplicationContext:

bằng BeanFactory như đoạn code sau:

thì bạn vẫn chạy ra kết quả như bình thường.

Vậy sự khác biệt giữa hai interface trên là gì? Tại sao mình chỉ dùng ApplicationContext mà không đả động gì đến BeanFactory. Trong bài viết này mình sẽ làm rõ để các bạn nắm nhé!

Điều đầu tiên mình cần nói là interface ApplicationContext được extends từ interface BeanFactory nhưng BeanFactory chỉ cung cấp những tính năng cơ bản cho Dependency Injection trong Spring còn ApplicationContext thì có thêm những chức năng khác nâng cao hơn.

Sự khác biệt đầu tiên của hai interface này là mặc dù cả hai đều cung cấp khả năng lấy đối tượng chúng ta cần trong Spring container bằng phương thức getBean() nhưng BeanFactory chỉ tạo ra đối tượng chúng ta cần khi chúng ta gọi phương thức getBean() còn ApplicationContext sẽ tạo hết tất cả các đối tượng chúng ta cần ngay khi bạn gọi đến Spring container.

Để minh chứng cho điều này, mình sẽ tiếp tục cái ví dụ mà mình đã làm trong bài viết trước nhé!

OK, bây giờ mình cần biết khi gọi đến Spring container, nó sẽ làm những gì? Ở level DEBUG, Spring sẽ cho chúng ta biết những điều đó các bạn ạ.

Vì thế mình sẽ thêm thư viện reload4j vào project sẵn có của mình và cấu hình cho chương trình của chúng ta chạy ở level DEBUG. Cụ thể như sau:

BeanFactory và ApplicationContext trong Spring

Nội dung tập tin log4j.properties

Thêm dependency của thư viện slf4j cho reload4j vào tập tin pom.xml

Bây giờ trong phương thức main của lớp Application, mình sẽ xóa hết tất cả code ngoại trừ dòng code gọi đến Spring container, nghĩa là lớp Application chỉ còn lại như sau:

Giờ mình sẽ chạy, các bạn sẽ thấy những dòng log sau đây:

Nếu bạn để ý kỹ những dòng log này, bạn sẽ thấy khi gọi đến Spring container bằng ApplicationContext, tất cả các đối tượng được khai báo trong tập tin cấu hình của Spring sẽ được khởi tạo ngay lập tức.

Bây giờ, chúng ta sẽ sử dụng BeanFactory thay vì ApplicationContext. Nội dung của tập tin Application sẽ như sau:

Rồi chạy, quan sát những dòng log:

bạn sẽ thấy không có đối tượng nào được tạo ra cả.

Nếu bây giờ các bạn thêm đoạn code getBean() thì đối tượng của chúng ta mới được tạo ra trong Spring container:

Nội dung log

Sự khác biệt thứ hai giữa hai interface này là ở đối tượng hiện thực của chúng. Đối với BeanFactory chúng ta thường dùng đối tượng hiện thực nó là DefaultListableBeanFactory còn ApplicationContext là ClassPathXmlApplicationContext.

Sự khác biệt thứ ba giữa hai interface này là ở khả năng hỗ trợ đa ngôn ngữ. Ví dụ như bạn có một câu được dịch ra bằng ba ngôn ngữ khác nhau: một Tiếng Việt, một Tiếng Anh, một là tiếng Pháp. ApplicationContext cho chúng ta khả năng lấy được nội dung của câu này ở ba ngôn ngữ khác nhau bằng phương thức getMessage(String code, Object[] args, Locale local) trong khi đó BeanFactory không hỗ trợ cho chúng ta làm điều này.

Ngoài ra, giữa hai interface này có thêm một số điểm khác nhau nữa nhưng vì bài viết này cũng đã dài mà những điểm khác nhau đó mình phải có ví dụ cụ thể để cho các bạn hiểu nên mình sẽ không liệt kê ra ở đây.

Tóm lại, ở bài viết này mục đích của mình là nói cho các bạn biết ngoài cách gọi khung chứa của Spring bằng ApplicationContext thì chúng ta còn có thể sử dụng BeanFactory. ApplicationContext hỗ trợ những chức năng khác mạnh mẽ hơn nên đa số chúng ta đều dùng interface này.

4.8/5 - (6 bình chọn)

8 thoughts on “BeanFactory và ApplicationContext trong Spring

  1. Tôi có xem qua các bài viết của bạn, thật sự nó rất bổ ích nó những người mới, tôi có 1 góp ý nhỏ là bạn không nên dich tất cả các thuật ngữ ra tiếng việt, thật sự có những cái mình để tiếng anh đọc dễ hiểu hơn tiếng việt, Ví dụ: Khung Chứa, khi mới đọc qua tôi bị bối rối với thuật ngữ này, nếu bạn giử nguyên thuật ngữ container thì mọi người sẽ dễ hiểu hơn.

    1. Thanks bạn, mình cũng đang dần không dịch qua Tiếng Việt nữa vì cũng cảm thấy như bạn vậy.

      Cảm ơn bạn đã đóng góp ý kiến cho Hướng Dẫn Java nhé.

  2. Anh tính nhận mà không biết nhận đệ tử để làm gì? Hihi.

    Đùa chút thôi, hồi đó anh năm cuối còn chưa biết phải làm gì huống hồ gì em. Đừng lo, 2 tháng thất nghiệp sau khi ra trường như anh cũng không lâu lắm đâu em.

Add Comment