寫兩個關於Spring中使用IoC的小例子,一個是半動態建立Bean,另外一個是全動態建立Bean,它們適合不一樣的應用場景。程序員
1、半動態:在一個實際項目中遇到過這樣的問題,項目組開發的某個系統具有在LED屏上顯示信息的功能。不一樣客戶那裏的LED屏各不相同,主要區別是驅動卡和顯示格式。若是每次換LED屏時都是靠程序員去替換不一樣實現的代碼,成本可想而知。那麼,在不修改既有代碼(甚至是不用編譯既有工程)的狀況下,怎樣才能讓系統的這個功能適應變化呢?web
首先抽象出一個接口,表明向LED屏打印的功能。spring
package com.mmh.printer; public interface LEDPrinter { public void print(String content); }
而後根據不一樣品牌的LED屏,編寫具體的打印功能。app
package com.mmh.printer; public class Brand1LEDPrinter implements LEDPrinter { @Override public void print(String content) { // 模擬不一樣品牌的LED顯示屏操做 System.out.println("這是品牌1的LED顯示內容: " + content); } }
緊接着編寫一個輔助類,客戶端程序經過它實現LED屏的打印功能。ide
package com.mmh.printer; public class LEDPrintHelper { private LEDPrinter printer; public void setPrinter(LEDPrinter printer) { this.printer = printer; } public void print(String content) { printer.print(content); } }
最後實現一個客戶端調用的演示程序。this
package com.mmh.main; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.mmh.printer.LEDPrintHelper; public class Application { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "appContext.xml"); LEDPrintHelper ledPrintHelper = (LEDPrintHelper) context.getBean("LEDPrintHelper"); ledPrintHelper.print("業務層產生的數據"); } }
在LED屏更換時,以上的代碼,無論是調用方的仍是被調用方的,都不須要作任何的修改。假設如今客戶使用的是Brand2品牌LED屏,那麼程序員只須要針對這種屏編寫具體操做便可。spa
package com.mmh.printer; public class Brand2LEDPrinter implements LEDPrinter { @Override public void print(String content) { // 模擬不一樣品牌的LED顯示屏操做 System.out.println("這是品牌2的LED顯示內容: " + content); } }
這個具體實現類徹底能夠封裝到一個單獨的jar中,那麼之前的既有代碼對於如今的開發人員能夠徹底透明。code
應對變化的功能是靠Spring的IoC來實現的。xml
<?xml version="1.0" encoding="UTF-8"?> <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.xsd"> <bean id="LEDPrintHelper" class="com.mmh.printer.LEDPrintHelper"> <property name="printer" ref="Brand1LEDPrinter" /> </bean> <bean id="Brand1LEDPrinter" class="com.mmh.printer.Brand1LEDPrinter" /> <bean id="Brand2LEDPrinter" class="com.mmh.printer.Brand2LEDPrinter" /> </beans>
該配置文件定義了三個Bean,LEDPrintHelper是調用程序的接口,Brand1LEDPrinter和Brand2LEDPrinter分別表明了兩種屏的具體操做。經過屬性注入的方式,開發人員手動修改(這就是半動態的意思)LEDPrintHelper的printer屬性值,從而更改LED屏的具體操做。blog
2、全動態:在實際項目中還遇到過這樣的問題,不一樣類型用戶的登陸實現方式是不一樣的,而且在系統的使用過程當中用戶的類型會不斷增長。那麼,在不修改既有代碼(甚至是不用編譯既有工程)的狀況下,怎樣才能讓系統的這個功能適應變化呢?
首先抽象一個接口,表明用戶登陸功能。
package com.mmh.login; public interface UserLogin { public boolean login(String username, String password); }
而後實現不一樣類型用戶的登陸過程。
package com.mmh.login; public class UserALogin implements UserLogin { @Override public boolean login(String username, String password) { System.out.println("根據UserA的業務邏輯處理登陸過程"); return true; } }
package com.mmh.login; public class UserBLogin implements UserLogin { @Override public boolean login(String username, String password) { System.out.println("根據UserB的業務邏輯處理登陸過程"); return true; } }
緊接着開放給客戶調用端一個統一的接口。這個接口在實際系統中常常會被實現爲一個web service。
package com.mmh.login; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class UserLoginService { private ApplicationContext context = new ClassPathXmlApplicationContext( "appContext.xml"); public boolean login(String username, String password, String logintype) { UserLogin userLogin = (UserLogin) context.getBean(logintype); return userLogin.login(username, password); } }
最後仍是編寫一個客戶調用的演示。
package com.mmh.main; import com.mmh.login.UserLoginService; public class Application { public static void main(String[] args) { UserLoginService service = new UserLoginService(); service.login("userA", "123456", "UserALogin"); service.login("userB", "123456", "UserBLogin"); } }
從上面的代碼能夠看到,不一樣的用戶能夠調用相同的接口進行不一樣的登陸操做,被調用程序根據用戶輸入的參數自動匹配登陸過程(這就是全動態的意思)。而且當系統增長用戶類型時,既有代碼不須要修改。應對變化的功能還是靠Spring的IoC來實現的。
<?xml version="1.0" encoding="UTF-8"?> <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.xsd"> <bean id="UserALogin" class="com.mmh.login.UserALogin" /> <bean id="UserBLogin" class="com.mmh.login.UserBLogin" /> </beans>