IOC&DI概述
配置Bean
- 配置形式:基于XML文件的方式;基于注解的方式
- Bean的配置方式:通过全类名(反射)、通过工厂方法(静态工厂方法&实例工厂方法)、FactoryBean
- IOC容器BeanFactory&ApplicationContext概述
- 依赖注入的方式:属性注入;构造器注入
- 注入属性值的细节
- 自动装配
- bean之间的关系:继承;依赖
- bean的作用域:singleton;prototype;WEB环境作用域
- 使用外部属性文件
- spEL
- IOC容器中的Bean的生命周期
- Spring4.x新特性:泛型依赖注入
IOC和DI
IOC(Inversion of Control):其思想是反转资源获取的方向。传统的资源查找方式要求组件向容器发起请求查找资源。作为回应,容器适时的返回资源。而应用了IOC之后,则是容器主动地将资源送给它所管理的组件,组件要做的仅仅是选择一种合适的方式来介绍资源。这种行为也被称为查找的被动形式
DI(Dependency Injection)–IOC的另一种表述方式:即组件以一些预先定义好的方式(例如:setter方法)接受来自如容器的资源注入。相对于IOC而言,这种表述更直接
IOC&DI原理
IOC前生 — 分离接口与实现
- 需求:生成HTML或PDF格式的不同类型的报表
IOC前生 — 采用工厂设计模式
IOC — 采用反转控制
Bean的配置方式
在Spring的IOC容器里配置Bean
在XML文件中通过bean节点来配置bean
1
2
3
4<!-- 通过全类名的方式来配置bean -->
<bean id = "helloWorld"
class = "com.spring.helloworld.HelloWorld">
</bean>id:Bean的名称
- 在IOC容器中必须是唯一
- 若id没有指定,Spring自动将权限定性类名作为Bean的名字
- id可以指定多个名字,名字之间可用逗号、分号、或者空格分隔
Spring容器
- 在SpringIOC容器容器读取Bean配置创建Bean实例之前,必须对它进行实例化。只有在容器实例化后,才可以从IOC容器里获取Bean实例并使用。
- Spring提供了两种类型的IOC容器实现。
- BeanFactory:IOC容器的基本实现。
- ApplicationContext:提供了更多的高级特性。是BeanFactory的子接口。
- BeanFactory是Spring框架的基础设施,面向Spring本身;ApplicationContext面向使用Spring框架的开发者,几乎所有的应用场合都直接使用ApplicationContext而非底层的BeanFactory
- 无论使用何种方式,配置文件时相同的。
ApplicationContext
- ApplicationContext的主要实现类:
- ClassPathXmlApplicationContext:从类路径下加载配置文件
- FileSystemXmlApplicationContext:从文件系统中加载配置文件
- ConfigurableApplicationContext扩展与ApplicationContext,新增两个主要方法:refresh()和close(),让ApplicationContext具有启动、刷新和关闭上下文的能力
- ApplicationContext在初始化上下文时就实例化所有单例的Bean。
- WebApplicationContext是专门为WEB应用而准备的,它允许从相对于WEB根目录的路径中完成初始化工作
从IOC容器中获取Bean
- BeanFactory
- FACTORY_BEAN_PREFIX:
String
- getBean(String):
Object
- getBean(String,Class<T>)
<T>:T
- getBean(Class<T>)
<T>:T
- getBean(String,Object…):
Object
- containsBean(String):
boolean
- isSingleton(String):
boolean
- isPrototype(String):
boolean
- isTypeMatch(String,Class<?>):
boolean
- getType(String):
Class<?>
- getAliases(String):
String[]
- FACTORY_BEAN_PREFIX:
- 具体实例
1
2
3
4
5
6
7
8//1.创建Spring 的IOC容器对象
//ApplicationContext 代表IOC容器
//ClassPathXmlApplicationContext:是ApplicationContext 接口的实现类
ApplicationContext act = new ClassPathXmlApplicationContext("spring-config.xml");
//2.从IOC容器中获取Bean实例
HelloWorld helloWorld = (HelloWorld)act.getBean("helloWorld");
//3.调用hello方法
helloWorld.hello();
属性注入
- 属性注入即通过setter方法注入Bean的属性值或依赖的对象
- 属性注入使用<property>元素,使用name属性指定Bean的属性名称,value属性或<value>子节点指定属性值
- 属性注入是实际应用中最常见的注入方式
1 | <!-- 通过全类名的方式来配置bean --> |
构造方法注入
- 通过构造方法注入Bean的属性值或者依赖的对象,它保证了Bean实例在实例化后就可以使用
- 构造器注入在<constructor-arg>元素里声明属性,<constructor-arg>中没有name属性
按顺序配置
1 | <!-- 通过构造方法来配置bean属性 --> |
按index配置
1 | <!-- 通过构造器注入属性值可以指定参数的位置 --> |
按type配置
1 | <!-- 通过构造器注入属性值可以指定参数的类型 --> |
提示: 通过构造器注入参数的类型和位置可以混合使用
字面值
- 字面值:可用字符串表示的值,可以通过<value>元素标签或value属性进行注入
- 基本数据类型及其封装类,String等类型都可以采用字面值注入的方式
- 若字面值中包含特殊字符,可用使用<![CDATA[]]>把字面值包裹起来
实例:
1 | <!-- 通过构造器注入属性值可以指定参数的位置和类型 --> |
输出结果:<ShangHai>
引用其它Bean
- 组成应用程序的Bean经常需要相互协作以完成应用程序的功能,要使Bean能够相互访问,就必须在Bean配置文件中指定对Bean的引用
- 在Bean的配置文件中,可用通过<ref>元素或ref属性为Bean的属性或构造器参数指定对Bean的引用
- 也可以在属性或构造器里包含Bean的声明,这样的Bean称为内部Bean
外部Bean实例:
1 | <!-- 通过方法注入属性值 --> |
内部Bean实例:
1 | <!-- 通过方法注入属性值 --> |
null值和级联属性
- 可以使用专用的<null/>元素标签为Bean的字符串或其它对象类型的属性注入null值
- 和Struts、Hiberante等框架一样,Spring支持级联属性的配置。
null值注入实例:
1 | <!-- 通过构造方法来配置bean属性 --> |
级联属性的配置:
1 | <!-- 通过方法注入属性值 --> |
集合属性
- 在Spring中可以通过一组内置的XML标签(例如:<list>,<set>或<map>)来配置集合属性
- 配置java.util.List类型的属性,需要指定<list>标签,在标签里包含一些元素,这些标签可以通过<value>指定简单的常量值,通过<ref>指定对其他Bean的引用,通过<bean>指定内置Bean定义。通过<null/>指定空元素,设置可以内嵌其他集合
- 数组的定义和List一样,都使用<list>
- 配置java.util.Set需要使用<set>标签,定义元素的方法与List一样。
- Java.util.Map通过<map>标签定义,<map>标签里可以使用多个<entry>作为子标签,每个条目包含一个键和一个值。
- 必须在<key>标签里定义键
- 因为键和值的类型没有限制,所以可以自由地为他们指定<value>,<ref>,<bean>或<null>元素。
- 可以将Map的键和值作为<entry>的属性定义:简单常量使用key和value来定义;Bean引用通过key-ref和value-ref属性定义
- 使用<props>定义java.util.Properties,该标签使用多个<prop>作为子标签,每个<prop>标签必须定义key属性.
List实例:
1 | <!-- 通过方法注入属性值 --> |
Map实例:
1 | <!-- 配置Map属性值 --> |
Properties实例:
1 | <!-- 配置Properties 属性值 --> |
使用utility scheme定义集合
- 使用基本的集合标签定义集合时,不能将集合作为独立的Bean定义,导致其他Bean无法引用该集合,所以无法在不同Bean之间共享集合。
- 可以使用util schema里的集合标签定义独立的集合Bean,需要注意的事,必须在<beans>根元素里添加退了 schema 定义。
配置单例集合Bean:
1 | <!-- 配置单例的集合Bean,以供多个bean进行引用,需要导入util命名空间 --> |
使用P命名空间
- 为了简化XML文件的配置,越来越多的XML的XML文件采用属性而飞子元素配置信息。
- Spring从2.5版本开始引入了一个新的p命名空间,可以通过<bean>元素属性的方式配置Bean的属性。
- 使用p命名空间后,基于XML的配置方式将进一步简化。
1 | <!-- 通过p命名空间为bean的属性赋值,需要先导入 p 命名空间,相对于传统的配置更加的简洁 --> |