有部分Java开发者对IoC和Di的概念有些混淆,认为二者是对等的,实际上IoC其实有两种方式:一种就是DI,而另一种是DL(Dependency Lookup,依赖查找).
前者是当前软件实体被动接受其依赖的其他自减被IoC容器注入,而后者则是当前软件试题主动去某个服务注册地查找起依赖的服务,概念之间的关系如图所示:
IoC相关概念示意图我们通常提到的SpringI哦C,实际上是指Spring框架提供的IoC容器实现(IoC Container),而使用Spring IoC容器的一个典型代码片段就是:
public class App {
public static void main(String[] args) {
ApplicationContext context = new FileSystemXmlApplicationContext("...");
//...
MockServoce service = context.getBean(MockService.class);
service.doSomething();
}
}
任何一个使用Spring框架构建的独立的Java应用(Standalone Java Application),通常都会存在一行类似于"context.getBean(...);"的代码中,实际上,折行代码做的就是DL的工作,而构建的任何一种IoC容器背后(比如BeanFactory或者ApplicationContent)发生的事情.则更多是DI的过程(也可能有部分DL的逻辑用于对接遗留系统).
Spring的IoC容器中发生的事情其实也很简单,总结下来即两个阶段:
(1)收集和注册Bean
(2) 分析和组装Bean
阶段一:收集和注册Bean
第一个阶段可以认为是构建和收集bean定义的阶段,在这个阶段中,我们可以通过XML或者JavaConfig代码的方式定义一些bean,然后通过手动组装或者让容器基于某些机制自动扫描的形式,将这些bean定义收集到IoC容器中。
假设我们以XML配置的形式来收集并注册单一Bean,一般形式如下:
<bean id="mockService" class="..MockServiceImpl">
...
</bean>l
如果嫌逐个手机Bean定义麻烦,想批量地注册到IoC容器中,我们也可以通过XML Schema形式的配置进行批量扫描并采集和注册:
<context:component-scan base_package=""com.keevol">
阶段二:分析和组装
当第一阶段完成后,我们可以先暂时认为IoC容器中充斥着一个个独立的Bean,它们之间没有任何关系.但实际上,它们之间是有依赖关系的,所以,IoC容器在第二阶段要干的事情就是分析这些已经在IoC容器之中的Bean,然后根据它们之间的依赖关系先后组装它们.如果IoC容器发现某个Bean依赖另一个Bean,它就会将这另一个Beann注入给依赖它的那个Bean,直到所有Beand的依赖都注入完成,所有Bean都"整装待发",这个IoC容器的工作即算完成.
至于分析和组装的依据,Spring框架最早是通过XML配置文件的形式在I描述Bean与Bean之间的关系的,随着Java业界研发技术和理念的转变,预计Java代码和Annotation元信息的描述方式也日渐兴盛(比如@Autowired和@Inject),但是不管是用哪种方式,都只是为了简化绑定逻辑描述的各种"表象",最终都是为本阶段的最终目的服务.
提示:
很多Java开发者一定认为Spring的XML配置文件是一种配置(Configration),但本质上,这些配置文件更应该是一种代码形式,XML在这里其实可以看作一种DSL,它用来表述的是Bean与Bean之间的依赖绑定关系,诸君还记得没有IoC容器的年代和自己写代码新建(nenw)对象并配置(set)依赖.
网友评论