Chúng ta hãy cố gắng hiểu nó thông qua hai ví dụ.
ví dụ 1
Trong những ngày trước, các ứng dụng được sử dụng để tạo lời nhắc lệnh chấp nhận đầu vào của người dùng lần lượt. Ngày nay, các khung công tác UI khởi tạo các thành phần UI khác nhau, lặp qua các sự kiện khác nhau của các thành phần UI đó (như di chuột, nhấp chuột, v.v.) và các chương trình người dùng / chính cung cấp các hook (ví dụ: trình nghe sự kiện UI trong Java) để nghe các sự kiện đó. Vì vậy, "điều khiển" luồng phần tử UI chính được chuyển từ chương trình người dùng sang khung UI. Trong những ngày trước, nó là trong chương trình người dùng.
Ví dụ 2
Xem xét lớp CustomerProcessor
dưới đây:
class CustomerProcessor
{
SqlCustRepo custRepo = new SqlCustRepo();
private void processCustomers()
{
Customers[] custs = custRepo.getAllCusts();
}
}
Nếu tôi muốn processCustomer()
độc lập với bất kỳ triển khai nào getAllCusts()
, không chỉ là do SqlCustRepo
tôi cung cấp , tôi sẽ cần phải thoát khỏi dòng: SqlCustRepo custRepo = new SqlCustRepo()
và thay thế nó bằng một cái gì đó chung chung hơn, có khả năng chấp nhận loại thực hiện khác nhau, như vậy processCustomers()
sẽ đơn giản hoạt động bất kỳ thực hiện được cung cấp. Mã ở trên (khởi tạo lớp bắt buộc SqlCustRepo
bằng logic chương trình chính) là một cách truyền thống và nó không đạt được mục tiêu tách rời processCustomers()
khỏi việc thực hiện getAllCusts()
. Khi đảo ngược điều khiển, bộ chứa khởi tạo lớp triển khai được yêu cầu (như được chỉ định bởi, nói cấu hình xml), đưa nó vào logic chương trình chính bị ràng buộc theo móc nối được chỉ định (nói theo @Autowired
chú thích hoặc getBean()
phương thức trong khung mùa xuân).
Hãy xem làm thế nào điều này có thể được thực hiện. Xem xét mã dưới đây.
Cấu hình
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="custRepo" class="JsonCustRepo" />
</beans>
CustRepo.java
interface ICustRepo
{ ... }
JsonCustRepo.java
class JsonCustRepo implements CustRepo
{ ... }
App.java
class App
{
public static void main(String[] args)
{
ApplicationContext context = new ClassPathXmlApplicationContext("Config.xml");
ICustRepo custRepo = (JsonCustRepo) context.getBean("custRepo");
}
}
Chúng ta cũng có thể có
class GraphCustRepo implements ICustRepo { ... }
và
<bean id="custRepo" class="GraphCustRepo">
và chúng tôi sẽ không cần thay đổi App.java.
Phía trên thùng chứa (là khung mùa xuân) có trách nhiệm quét tệp xml, khởi tạo bean loại cụ thể và đưa nó vào chương trình người dùng. Chương trình người dùng không có quyền kiểm soát lớp nào được khởi tạo.
PS: IoC là khái niệm chung và đạt được theo nhiều cách. Trên ví dụ đạt được nó bằng cách tiêm phụ thuộc.
Tham khảo: Bài viết của Martin Fowler .