传统应用程序示意图
当有了IoC/DI的容器后,在客户端类中不再主动去创建这些对象了,如图所示:
POJO:
Plain Old Java Objects
简单的Java对象
IOC:
Inversion of Control
控制反转
控制反转还有一个名字叫做依赖注入(Dependency Injection) DI
IoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述
DI:
Dependency Injection
依赖注入
AOP:Aspect Oriented Programming
IOC:
Spring IoC容器目的就是管理Bean,这些Bean将根据配置文件中的Bean定义进行创建,而Bean定义在容器内部由BeanDefinition对象表示
IoC容器就是具有依赖注入功能的容器,IoC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
应用程序无需直接在代码中new相关的对象,应用程序由IoC容器进行组装。在Spring中BeanFactory是IoC容器的实际代表者。
Spring IoC容器通过读取配置文件中的配置元数据,通过元数据对应用中的各个对象进行实例化及装配。
一般使用基于xml配置文件进行配置元数据,而且Spring与配置文件完全解耦的,可以使用其他任何可能的方式进行配置元数据,比如注解、基于java文件的、基于属性文件的配置都可以。
IoC容器:
在SpringIoc容器的代表就是org.springframework.beans包中的BeanFactory接口,BeanFactory接口提供了IoC容器最基本功能;
而org.springframework.context包下的ApplicationContext接口扩展了BeanFactory,还提供了与AOP集成、国际化处理、事件传播及提供不同层次的context实现 (如针对web应用的WebApplicationContext)。
ApplicationContext完全继承BeanFactory,因而BeanFactory所具有的语义也适用于ApplicationContext。
简单说, BeanFactory提供了IoC容器最基本功能,而 ApplicationContext 则增加了更多支持企业级功能支持。
注意:BeanFactory没有如aop、消息、资源加载、事件等功能
常用容器:
1 XmlBeanFactory:BeanFactory实现,提供基本的IoC容器功能,可以从classpath或文件系统等获取资源;
(1) File file = new File("fileSystemConfig.xml");
Resource resource = new FileSystemResource(file);
BeanFactory beanFactory = new XmlBeanFactory(resource);
(2)
Resource resource = new ClassPathResource("classpath.xml");
BeanFactory beanFactory = new XmlBeanFactory(resource);
2 ClassPathXmlApplicationContext:
ApplicationContext实现,从classpath获取配置文件;
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath.xml");
3 FileSystemXmlApplicationContext:
ApplicationContext实现,从文件系统获取配置文件。
BeanFactory beanFactory = new FileSystemXmlApplicationContext("fileSystemConfig.xml");
IoC容器如何工作(xml配置方式):
一、准备配置文件:就像前边Hello World配置文件一样,在配置文件中声明Bean定义也就是为Bean配置元数据。
二、由IoC容器进行解析元数据: IoC容器的Bean Reader读取并解析配置文件,根据定义生成BeanDefinition配置元数据对象,IoC容器根据BeanDefinition进行实例化、配置及组装Bean。
三、实例化IoC容器:由客户端实例化容器,获取需要的Bean。
实例化Bean:
传统应用程序可以通过new和反射方式进行实例化Bean。而Spring IoC容器则需要根据Bean定义里的配置元数据使用反射机制来创建Bean。
在Spring IoC容器中根据Bean定义创建Bean主要有以下几种方式:
一、使用构造器实例化Bean
使用空构造器进行定义
使用有参数构造器进行定义
使用此中方式,可以使用<constructor-arg >标签指定构造器参数值,
其中index表示位置,value表示常量值,也可以指定引用,指定引用使用ref来引用另一个Bean定义
<bean name="bean2" class="cn.javass.spring.chapter2.HelloImpl2">
<!-- 指定构造器参数 -->
<constructor-arg index="0" value="Hello Spring!"/>
</bean>
二、使用静态工厂方式实例化Bean
指定factory-method属性来指定实例化Bean的方法
<!-- 使用静态工厂方法 -->
<bean id="bean3" class="cn.javass.spring.chapter2.HelloApiStaticFactory" factory-method="newInstance">
<constructor-arg index="0" value="Hello Spring!"/>
</bean>
三、使用实例工厂方法实例化Bean
使用factory-bean属性来指定工厂Bean,factory-method属性指定实例化Bean的方法
<!—1、定义实例工厂Bean -->
<bean id="beanInstanceFactory" class="cn.javass.spring.chapter2.HelloApiInstanceFactory"/>
<!—2、使用实例工厂Bean创建Bean -->
<bean id="bean4" factory-bean="beanInstanceFactory"
factory-method="newInstance">
<constructor-arg index="0" value="Hello Spring!"></constructor-arg>
</bean>