Spring là gì?
Spring là một framework mã nguồn mở trên nền tảng Java. Spring có thể được sử dụng trong bất cứ ứng dụng Java nào, ngoài ra nó còn cung cấp sẵn nhiều extension cho phép khả năng xây dựng ứng dụng web trên nền tảng J2EE.
Spring cho phép lập trình dựa vào POJO làm cho việc phát triển các ứng dụng trở nên dễ dàng và đơn giản hơn từ các ứng dụng J2SE tới J2EE.
Inversion of Control và Dependency Injection
Inversion of Control (IoC) là một programming principle nói về việc đảo ngược lại (inverse) cách điều khiển với object, behavior, process... Như khi sử dụng library và framework: framework yêu cầu mình phải chèn implement vào những chỗ cần thiết để framework sử dụng trong khi library thì mình sẽ gọi hàm từ library cung cấp.
IoC chỉ mang tính khái niệm cho những biểu hiện chung của sự đảo ngược (so với tư duy truyền thống, bởi vì nó mang tính mẫu hình chung nên nhiều người cũng gọi IoC là design pattern), một trong những implement của IoC về dependency hay được nói đến trong OOP là Dependency Injection (DI). DI giải quyết vấn đề về sự phụ thuộc khi có những ràng buộc has-a trong lập trình hướng đối tượng. Chuyển sự phụ thuộc đó ra ngoài bản thân đối tượng và ràng buộc ở nơi nó được thực thi.
DI chỉ là 1 thể hiện của IoC. Trong Spring, khái niệm IoC nói đến nhiều khía cạnh khác nhau chứ không chỉ có Injection.
IoC trong Spring
Spring IoC container là module triển khai IoC trong Spring với các thành phần cơ bản ở trong 2 packages org.springframework.beans và org.springframework.context. Trong đó BeanFactory và ApplicationContext là 2 interfaces đại diện cho IoC container.
IoC container cho phép đối tượng được tạo ra bởi framework bằng cấu hình (configurable metadata). Đấy là biểu hiện của inversion của việc construct, assembly object từ chỗ phải tự cung cấp instant cho framework thì lại đưa cho framework control.
BeanFactory cung cấp cách thức làm việc với tất cả các loại đối tượng, ApplicationContext kế thừa BeanFactory, mở rộng chức năng để phù hợp với những ứng dụng trên nền tảng J2EE như đa ngôn ngữ - il8n, event (consume - provide) và khả năng tích hợp dễ dàng với Aspect Oriented Programming, cung cấp context cho từng layer trong ứng dụng. Cùng xem những interface được ApplicationContext kế thừa để hiểu sơ một vài cách thức làm việc mà ApplicationContext có thể cung cấp:
 |
| Application Context Hierarchy |
Spring Bean
Một object được tạo, quản lý bởi IoC container (tạo ra bởi ApplicationContext hoặc BeanFactory) đều được gọi là Bean. Spring Bean là một trong những khái niệm cốt lõi của Spring.
Configurable Metadata
Để IoC container của Spring có thể tạo, gán giá trị cho bean thì cần phải có những bản cấu hình mô tả dữ liệu gọi là configurable metadata. Configurable Metadata có thể là XML, Annotation hoặc Java code.
Cùng với việc sử dụng POJO programming model và metadata, IoC container của Spring đã giải quyết được việc tạo, gán giá trị, liên kết đối tượng một cách đơn giản và hiệu quả. Sơ đồ sau mô tả high-level cách mà Spring IoC Container hoạt động:
 |
Spring IoC diagram. Source: spring.io
|
Dependency Injection
Nếu đã có được ý tưởng về định nghĩa cũng như cách IoC vận hành trong Spring thì DI sẽ dễ hiểu hơn rất nhiều. Để tạo bean, IoC container sẽ phải đọc POJO và Configurable metadata. Với primitive property thì Spring sẽ tạo và gán giá trị nó dễ dàng, nhưng đối với Object thì sao? Đơn giản là IoC container cũng sẽ tìm POJO và metadata của bean cần tạo và wire nó vào. Đấy chính là quá trình inject bằng cách wire object field (dependency) tới bean tạo từ IoC Container.
Có 2 cách inject dependency đó là Constructor-based và Setter-based. Tùy vào từng trường hợp mà việc sử dụng cách nào sẽ được cân nhắc, điểm khác biệt của 2 cách đó là constructor-based thì inject dependency vào khi tạo bean, còn setter-based inject dependency sau khi tạo bean.
Sẽ có trường hợp 2 đối tượng có dependency lẫn nhau (Circular dependencies). Vấn đề này như cách mà Spring nói trong manual của họ là "You can generally trust Spring to do the right thing", bằng cách là "Spring sets properties and resolves dependencies as late as possible, when the bean is actually created". Còn trường hợp mà dependency được inject thông qua constructor thì chắc chắn việc tạo instance trước rồi inject sau là bất khả thi. Trong trường hợp đó Spring sẽ ném lỗi BeanCurrentlyInCreationException tại runtime. Đấy cũng là lý do mà tại sao ApplicationContext tạo bean ngay tại thời điểm start Spring, pre-initialize, so với BeanFactory là lazy-initialize, đánh đổi thời gian khởi động và tăng bộ nhớ với việc phát hiện ra những lỗi trong cấu hình cũng như inject dependency như thế này. Tất nhiên là việc cấu hình lazy-initialize và pre-initialize hoàn toàn khả thi.
Trên đây tóm tắt một vài khái niệm cơ bản trong Spring và cách chúng hoạt động. Hiểu được những khái niệm này là tiền đề để hiểu được Spring Framework.
No comments:
Post a Comment