写两个关于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>