您的位置:首页 > 编程语言 > Java开发

第二章 IoC 之 2.2 IoC容器基本原理

2016-01-19 00:05 441 查看

2.2.1 IoC容器的概念

IoC容器就是具有依赖注入功能的容器,IoC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。应用程序无需直接在代码中new相关的对象。应用程序由IoC容器进行组装。在Spring中BeanFactory是IoC容器的实际代表者。

Spring IoC容器是如何知道哪些是它管理的对象呢?这就需要配置文件,Spring IoC容器通过读取配置文件中的配置元数据,通过元数据对应用中的各个对象进行实例化及装配。一般使用基于xml配置文件进行配置元数据,而且Spring与配置文件完全解耦,可以使用其他任何可能的方式进行配置元数据,比如注解,基于java文件的,基于属性文件的配置都可以。

那Spring IoC容器管理的对象叫什么呢?

2.2.2 Bean的概念

由IoC容器管理的那些组成你应用程序的对象我们就叫它Bean,Bean就是由Spring 容器初始化、装配及管理的对象,除此之外,bean就与应用程序中的其他对象没有什么区别了。那IoC怎样确定如何实例化Bean,管理Bean之间的依赖关系以及管理Bean呢?这就需要配置元数据,在Spring中由BeanDefinition代表,后边会有详细介绍,配置元数据指定如何实例化Bean,如何组装Bean等。概念知道的差不多了,让我们来做个简单的例子。

2.2.3 Hello World

一、配置环境:

JDK安装:安装最新的JDK,至少需要Java1.5及以上。

开发工具:我们使用的是EclipseIDE for Java (eclipse-jee-helios-SR2)。

Spring依赖:Spring-framework-3.2.4.RELEASE

                            下载地址:http://repo.spring.io/release/org/springframework/spring/

 

二、开始Spring Hello World之旅

1.准备所需的jar包:

核心jar包:

spring-core-3.2.4.RELEASE.jar

spring-beans-3.2.4.RELEASE.jar

spring-context-3.2.4.RELEASE.jar

spring-expression-3.2.4.RELEASE.jar

依赖的jar包:

                            commons-logging-1.2.jar

log4j-1.2.17.jar

2.创建标准Java工程:

 1)创建项目,名称为:spring_helloworld

 2) 添加spring所需jar包和Junit4

 3)项目搭建好了,让我们来开发接口,此处我们只需实现打印“Hello World”,所有我们定义一个“sayHello”接口,代码如下:

package com.gaoyinghao.spring.helloworld.service;
public interface IHelloWorldService {
public void sayHelloWorld();
}

4)接口开发好了,让我们通过实现接口来完成打印“Hello World!”功能。

<pre name="code" class="java">package com.gaoyinghao.spring.helloworld.service.impl;
importcom.gaoyinghao.spring.helloworld.service.IHelloWorldService;

public class HelloWorldServiceImpl implements IHelloWorldService{

@Override
public void sayHelloWorld() {
System.out.println("HelloWorld!");
}
}



 5)接口和实现都开发好了,那如何使用Spring IoC容器来管理他们呢?这就需要配置文件,让IoC容器知道要管理哪些对象,让我们来配置文件helloworld.xml(放到sources目录下)

<?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"> <!-- id表示这个组件的名字,class表示组件类 -->
<bean id="helloWorldService" class="com.gaoyinghao.spring.helloworld.service.impl.HelloWorldServiceImpl"></bean>
</beans>
6)现在万事具备,那如何获取IoC容器并完成我们所需要的功能呢?首先应该实例化一个IoC容器,然后从容器中获取需要的对象,然后调用接口完成我们需要的功能,代码示例如下:

package com.gaoyinghao.spring.helloworld.service;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
importorg.springframework.context.support.ClassPathXmlApplicationContext;

public class IHelloWorldServiceTest {

@Test
public void testSayHelloWorld() {
//1、读取配置文件实例化一个IoC容器
ApplicationContext context = new ClassPathXmlApplicationContext("helloworld.xml");
//2、从容器中获取Bean,注意此处完全“面向接口编程,而不是面向实现”
IHelloWorldService helloWorldService = context.getBean("helloWorldService",IHelloWorldService.class);
//3、执行业务逻辑
helloWorldService.sayHelloWorld();
}
}

 7)自此一个完整的SpringHello World已完成,是不是很简单,让我们深入理解下容器和Bean吧。

2.2.4 详解IoC容器

在Spring 中,IoC容器的代表就是org.springframework.beans包中的BeanFactory接口,BeanFactory接口提供了IoC容器最基本功能,而org.springframework.context包下的ApplicationContext接口扩展了BeanFactory,还提供了与SpringAOP集成,国际化处理,事件传播及提供不同层次的context实现(如针对web应用的WebApplicationContext)。简单说,BeanFactory提供了IoC容器最基本功能,而ApplicationContext则增加了更多支持企业级功能支持。ApplicationContext完全继承了BeanFactory,因而BeanFactory所具有的语义也适用于ApplicationContext。

容器实现一览:

XmlBeanFactory:BeanFactory实现,提供基本的IoC容器功能,可以从classpath或文件系统等获取资源:

(1)      File file = new File(“beanx.xml”);

Resource resource = new FileSystemResource(file);

BeanFactory beanFactory = new XmlBeanFactory(resource);

    (2)   Resource resource = newClassPathResource(“classpath.xml”);

               BeanFactory beanFactory = newXmlBeanFactory(resource);

ClasspathXmlApplicationContext:ApplicationContext实现,从classpath获取配置资源;

         BeanFactorybeanFactory = new ClassPathXmlApplicationContext(“classpath.xml”);

FileSystemXmlApplicationContext:ApplicationContext实现,从文件系统获取资源文件;

         BeanFactorybeanFactory = new FileSystemXmlApplicationContext(“fileSystemConfig.xml”);

 

ApplicationContext接口获取Bean方法简介:

Object getBean(String name):根据名称返回一个Bean,客户端需要自己进行类型转换;

T getBean(String name,Class<T>requiredType):根据名称和指定的类型返回一个Bean,客户端无需自己进行类型转换,如果类型转换失败,容器抛出异常。

T getBean(Class<T> requiredType):根据指定的类型返回一个Bean,客户端无需自己进行类型转换,如果没有或有多于一个Bean存在容器将抛出异常。

Map<String,T>getBeansOfType(Class<T> type):根据指定的类型返回一个键为名字和值为Bean对象的Map,如果没有
4000
Bean对象存在,则返回空的Map。

 

让我们来看下IoC容器到底是如何工作的。在此我们以xml配置方式来分析一下:

一、准备配置文件:就像前边HelloWorld配置文件一样,在配置文件中声明Bean定义,也就是为Bean配置元数据。

二、由IoC容器进行解析元数据:IoC容器的BeanReader读取并解析配置文件,根据定义生成BeanDefinition配置元数据对象,IoC容器根据BeanDefinition进行实例化,配置及组装Bean。

三、实例化IoC容器:由客户端实例化容器,获取需要的Bean。

整个过程是不是很简单,执行过程如下图,其实IoC容器很容易使用,主要是如何进行Bean定义。



2.2.5 小结

除了测试程序代码外,也就是程序入口,所有代码都没有出现Spring任何组件,而且所有我们写的代码没有实现框架拥有的接口,因而能非常容易的替换掉Spring,是不是非入侵。

客户端代码完全面向接口编程,无需知道实现类,可以通过修改配置文件来更换接口实现,客户端代码不需要任何修改,是不是低耦合。

如果在开发初期没有真正的实现,我们可以模拟一个实现来测试,不耦合代码,是不是很方便测试。

Bean之间几乎没有依赖关系,是不是很容易重用。

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息