1.ioc定义
IoC就是Inversion of Control,控制反转。
IoC 的概念是Michael Mattson在1996年一篇讨论面向对象框架(Object Oriented Frameworks)的文章中提出的。面向对象设计及编程(OOD/OOP)的基本思想简单地说就是把复杂软件系统分解成通过接口相互合作的对象。这些对象类的内部实现之间并不互相牵扯,因而降低了问题的复杂性,且可独立灵活地被重用和扩展。经典面向对象的编程语言(如C++,Java)的侧重点就是提供语言机制来方便并简化这种基于对象类的分解,重用和扩展。
在基于模块化软件组装部署配置框架设计中,Michael Mattson提出了基于IOC容器的IoC设计原则。依照该原则,业务逻辑模块并不需知道更不必调用组件框架的服务,例如不用关心和调用其factory或lookup其directory或context等。软件的组装部署和配置完全是由Ioc容器反过来主动控制业务逻辑模块来安排。Michael Mattson用所谓的好莱坞原则(Hollywood Principle)“别来找我,到时候,我会去找你”(don't call me, I will call you)形象地比喻了这一设计思想。这个比喻中的“我”指的是Ioc容器,“你”则是被其调遣配置的一个组件。
在Java开发中,IoC地实现通过工厂模式,由工厂新建所需要的类。在j2ee轻量级框架中,则由ioc容器来控制。ioc容器的一个著名实现是Spring.另外一个Guice,google名下的产物.这两种实现代表了ioc技术的两个发展方向。他们之间的最根本的区别在于,spring采用XML文件的形式来配置依赖注入关系;而Guice完全通过Java 5注解实现类型安全的注入。
2.spring的ioc容器实现
使用spring的方式,创建一个由spring ioc容器控制的ioc的应用程序。
1)定义用于接口,打印“hello,world”消息
public interface MessageProvider { public String getMessage(); }
2)实现这个接口
public class MessageHello implements MessageProvider { public String getMessage() { String message = "hello,world"; return message; } }
3)setter injection
public class HelloWorld { private MessageProvider provider; public void setProvider(MessageProvider provider) { this.provider = provider; } public void showMessage() { System.out.println(provider.getMessage()); } }
4)配置依赖注入关系
在applicationContext.xml中配置:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="helloBean" class="test.spring.HelloWorld"> <property name="provider"> <ref local="helloProvider"/> </property> </bean> <bean id="helloProvider" class="test.spring.MessageHello"></bean> </beans>
5)创建测试类
public class ShowHello { public static void main(String[] args){ try{ XmlBeanFactory factory =new XmlBeanFactory(new FileSystemResource("src/applicationContext.xml")); HelloWorld messageReader = (HelloWorld)factory.getBean("helloBean"); messageReader.showMessage(); }catch(Exception ex){ System.out.println(ex.toString()); } } }
运行测试类,控制台输出:Hello,World!
3.Guice的ioc容器实现
Guice下载链接(http://code.google.com/p/google-guice/downloads/list)
1)定义接口
public interface MessageProvider{ void myMethod(); }
2)定义实现类
public class MessageHello implements MessageProvider{ public void myMethod(){ System.out.println("Hello,World!"); } }
3)Guice进行注入类
public class Client{ MessageProvider service; @Inject //告诉容器,这里的service对象的引用,需要进行注入 void injectMessageProvider(MessageProvider service){ //这里的方法名字可以任意定义 this.service = service; } public void myMethod(){ service.myMethod(); } }
4)定义Guice的Module文件告诉容器如何进行注入
import com.google.inject.Binder; import com.google.inject.Module; import com.google.inject.Scopes; public class MyModule implements Module{ public void configure(Binder binder){ binder.bind(MessageProvider.class).to(MessageHello.class).in(Scopes.SINGLETON); // 这句代码的意思是说:运行时动态的将MessageHello对象赋给MessageProvider定义的对象,而且这个对象是单例的。 } }
5)创建测试类
import com.google.inject.Guice; import com.google.inject.Injector; public class Test{ public static void main(String[] args){ MyModule module = new MyModule(); // 定义注射规则 Injector injector = Guice.createInjector(module); // 根据注射规则,生成注射者 Client client = new Client(); injector.injectMembers(client); // 注射者将需要注射的bean,按照规则,把client这个客户端进行注射 client.myMethod(); } }
运行测试类,控制台输出:Hello,World!