控制反转(
IOC
)
Inversion of Control
或依赖注入(
DI
)
Dependency Injection
.
The idea is simple: separate(分离或解耦) dependency(依赖关系) management from the main business code
![](https://p-blog.csdn.net/images/p_blog_csdn_net/danning/3efb2318de13440c8bcde7bd1f177300.png)
Figure 1: Injection of Control(去除或减弱)the dependency(依赖关系) between SessionFactoryImpl(即在Service类中注入了一个SessionFactory接口). and Service. So, we add a special class called Assembler that “injects” the dependency into Service using plain setter calls
Let’s look more closely at this figure. Here we have a Service that needs a SessionFactory to perform queries into a database. The goal is to remove
Spring can provide you with a
SessionFactory implementation for many different persistence frameworks like
Hibernate.(spring能提供不同
SessionFactory
接口的实现。)
下面仅用JSF的
控制反转(
IOC
)Inversion of Control进行说明。
SessionFactory and
Service are assembled together in the
faces-config.xml configuration
![](https://p-blog.csdn.net/images/p_blog_csdn_net/danning/14edf6a96fca481ea6d604679d85c9fb.png)
Figure 2: Session Factory Interface
![](https://p-blog.csdn.net/images/p_blog_csdn_net/danning/0291a56fbaa549dca3f40ba8d7bd6d48.png)
Figure 3: Session Factory Implementation
![](https://p-blog.csdn.net/images/p_blog_csdn_net/danning/546b60ac625c4a8eaca73aa98cf335b5.png)
Figure 4: Service Implementation
![](https://p-blog.csdn.net/images/p_blog_csdn_net/danning/59c344680b764044bb795783571218e1.png)
Figure 5: faces-config.xml File for JSF Configuration
![](https://p-blog.csdn.net/images/p_blog_csdn_net/danning/21a9f5ec99104dd096d87e7a5fa46607.png)
Ioc
模式(
Dependency Injection
模式)有三种:
第一种类型
|
从
JNDI
或
ServiceManager
等获得被调用者,这里类似
ServiceLocator
模式。
|
1. EJB/J2EE 2. Avalon ( Apache 的一个复杂使用不多的项目) |
第二种类型
|
使用
JavaBeans
的
setter
方法
|
1. Spring Framework, 2. WebWork/XWork |
第三种类型
|
在构造方法中实现依赖
|
1. PicoContainer, 2. HiveMind |
依赖注入的形式主要有三种,我分别将它们叫做构造子注入(Constructor Injection)、设值方法注入(Setter Injection)和接口注入(Interface Injection)。这三种注入形式分别就是 type 1 IoC(接口注入)、type 2 IoC(设值方法注入)和 type 3 IoC(构造子注入)。
Dependency Injection模式并不是打破这层依赖关系的唯一手段,另一种方法是使用
Service Locator模式。
我们面临Service Locator和 Dependency Injection之间的选择。应该注意,尽管我们前面那个简单的例子不足以表现出来,实际上这两个模式都提供了基本的解耦合能力——无论使用哪个模式,应用程序代码都不依赖于服务接口的具体实现。两者之间最重要的区别在于:这个“具体实现”以什么方式提供给应用程序代码。使用 Service Locator 模式时,应用程序代码直接向服务定位器发送一个消息,明确要求服务的实现;使用 Dependency Injection模式时,应用程序代码不发出显式的请求,服务的实现自然会出现在应用程序代码中,这也就是所谓“控制反转”.
一个关键的区别在于:使用 Service Locator 模式时,服务的使用者必须依赖于服务定位器。定位器可以隐藏使用者对服务具体实现的依赖,但你必须首先看到定位器本身。所以,问题的答案就很明朗了:选择 Service Locator还是 Dependency Injection,取决于“对定位器的依赖”是否会给你带来麻烦。