一.IOC和DI
1.IOC(Inversion of Control)
其思想是反转资源获取的方向。传统的资源查找方式要求组件向容器发起请求查找资源,做为回应,容器适时的返回资源;而应用了IOC以后,则是容器主动的将资源推送给它所管理的组件,组件所要作的仅是选择一种合适的方式来接收资源。这种行为也被成为查找的被动形式。java
2.DI(Dependency Injection)
IOC的另外一种表达方式:即组件的一些预先定义好的方式(例如:setter方法)接受来自如容器的资源注入。相对于IOC而言,这种表述更直接。web

3.IOC的前世此生
使用这样一个需求,生成HTML或者PDF格式的不一样类型的报表为例,说明IOC的演变。
①分离接口设计正则表达式

②采用工厂模式spring

③采用反转控制数组

二.spring配置bean
1.在spring的IOC容器里面配置Bean。
在xml文件中经过bean节点来配置beanspring-mvc
<bean id="helloWorld"
class="com.desperado.helloworld.HelloWorld >
</bean>
id:Bean的名称。服务器
- 在IOC容器中必须是惟一的.
- 若id没有指定,Spring会自动将全限定性类名做为Bean名称。
- id能够指定多个名字,名字之间能够用逗号、分号、或空格隔开。
2.Spring容器
- 在Spring IOC容器读取Bean配置建立Bean实例以前,必须对它进行实例化。只有在容器实例化以后,才能够从IOC容器里面获取Bean实例并使用。
- Spring提供了两种类型的IOC容器实现
- BeanFactory:IOC容器的基本实现。
- ApplicationContext:提供了更多的高级特性,是BeanFactory的子接口。
- BeanFactory是Spring框架的基础设施,面向Spring自己。ApplicationContext面向使用Spring框架的开发者,几乎全部的应用场合都直接使用ApplicationContext而非底层的BeanFactory。
- 不管使用何种方式,配置文件是相同的。
3.ApplicationContext
- ApplicationContext的主要实现类:
- ClassPathXmlApplicationContext:从类路径下面加载配置文件。
- FileSystemXmlApplicationContext:从文件系统中加载配置文件。
- ConfigurableApplicationContext扩展于ApplicationContext,新增长两个主要方法:refresh()和close(),让ApplicationContext具备启动、刷新和关闭上下文的能力。
- ApplicationContext在初始化上下文时就实例化全部单例的Bean。
- WebApplicationContext是专门为WEB应用而准备的,它容许从相对于WEB根目录的路径中完成初始化工做.。

- 调用ApplicationContext的getBean()方法能够获取到Bean。
4.依赖注入的三种方式
- 属性注入
属性注入即经过setter方法注入Bean的属性值或依赖的对象。
属性注入使用
元素,使用name属性指定Bean的属性名称,value属性或
子节点指定属性值。
属性注入是实际应用中最经常使用的注入方式。
<bean id="helloWorld" class="com.desperado.helloworld.HelloWorld">
<property name="userName" value="desperado"></property>
</bean>
- 构造器注入
经过构造方法注入Bean的属性值或依赖的对象,它保证了Bean实例在实例化后就可使用。
构造器注入在
元素里声明属性,
中没有name属性。
<bean id="car" class ="com.desperado.helloworld.Car">
<constructor-arg value="奥迪" index="0"></constructor-arg>
<constructor-arg value="奔驰" index="1"></constructor-arg>
<constructor-arg value="5000" index="2"></constructor-arg>
</bean>
<bean id="car" class ="com.desperado.helloworld.Car">
<constructor-arg value="奥迪" type="java.lang.String"></constructor-arg>
<constructor-arg value="奔驰" type="java.lang.String"></constructor-arg>
<constructor-arg value="5000" type="java.lang.double"></constructor-arg>
</bean>
工厂方法注入(不多使用,不推荐)session
- 注入属性值细节
- 字面值:可用字符串表示的值,能够经过
元素标签或value属性进行注入。
- 基本数据类型及其封装类、String等类型均可以采起字面值的注入。
- 若字面值中包含特殊字符,可使用<[CDATA[]]把字面值包裹起来。
5. 引用其余Bean
- 组成应用程序的Bean常常须要相互协做以完成应用程序的功能,要使Bean可以相互访问,就必须在Bean配置文件中指定对Bean的引用。
- 在Bean的配置文件中,能够经过
[
元素或ref属性为Bean的属性或构造器参数指定对Bean的引用。
]
- 也能够在属性或构造器里包含Bean的声明,这样的Bean成为内部Bean。
<bean id="service" class="com.desperado.helloworld.Service"></bean>
<bean id="action" class="com.desperado.helloworld.Action">
<property name="service" ref="service"></property>
</bean>
6.内部bean
- 当Bean实例仅仅给一个特定的属性使用时,能够将其声明为内部Bean,内部Bean声明直接包含在
或者
元素里,不须要设置任何id或name属性。
内部Bean不能使用在任何其余部分。mvc
7.null值和级联属性
- 可使用专用的
元素标签为Bean的字符串或其它对象类型的属性注入null值。
Spring支持级联属性的配置。app
8.集合属性
- 在Spring中能够经过一组内置的xml标签(例如
,
,
- 配置java.util.List类型的属性,须要指定
标签,在标签里包含一些元素。这些标签能够经过
指定简单的常量值。这些标签能够经过
指定简单的常量值,经过
[
指定对其余Bean的引用。经过
指定内置Bean的定义,经过
指定空元素,甚至能够内嵌其余集合。
]
- 数组的定义和List同样,都使用
- 配置java.util.Set须要使用
标签,定义元素的方法与List同样。
- java.lang.Map经过
- 必须在
标签里定义键。
- 由于键和值的类型没有限制,索引能够自由的为它们指定
,
[
,
或
元素。
]
- 能够将Map的键和值做为
的属性定义:简单常量使用key和value定义;Bean引用经过key-ref和value-ref属性定义。
- 使用
定义java.util.Properties,该标签使用多个
做为子标签,每一个
标签必须定义key属性。
9.使用utility scheme定义集合
- 使用基本的集合标签订义集合时,不能将集合做为独立的Bean定义,致使其余Bean没法引用该集合,因此没法再不一样Bean之间共享集合。
- 可使用util schema里的集合标签订义独立的集合Bean。须要注意的是,必须在
根元素里添加util schema定义。
10.使用P命名空间
- 为了将XML文件的配置愈来愈多的XML文件采用属性而非子元素配置信息。
- Spring从2.5开始引入了一个新的p命名空间,能够经过
元素属性的方式配置Bean的属性。
-使用p命名空间后,基于XML的配置方式将进一步简化。
三.XML配置里的Bean自动装配
- Spring IOC容器能够自动装配Bean,须要作的仅仅是在
的autowire属性里指定自动装配的模式。
- byType(根据类型自动装配):若IOC容器中有多个与目标Bean类型一致的Bean。在这种状况下,Spring将没法断定哪一个Bean最适合该属性,索引不能执行自动装配。
- byName(根据名称自动装配):必须将目标Bean的名称和属性名设置的彻底相同。
- constructor(经过构造器自动装配):当Bean中存在多个构造器时,此种自动装配方式将会很复杂,不推荐使用。
缺点
- 在Bean配置文件里设置autowire属性进行自动装配将会装配Bean的全部属性,而后,若只但愿装配个别属性时,autowire属性就不够灵活了。
- autowire属性要么根据类型自动装配,那么根据名称自动装配,不能二者兼而有之。
- 通常状况下,在实际的项目之中不多使用自动装配功能,由于和自动装配功能所带来的好处比起来,明确清晰的配置文档更好。
四.Bean之间的关系:继承和依赖
1.继承Bean配置
- Spring容许继承Bean的配置,被继承的Bean称为父bean,继承这个父bean的bean称为子bean。
- 子Bean从父Bean中继承配置,包括Bean的属性配置。
- 子Bean也能够覆盖从父Bean继承过来的配置。
- 父Bean能够做为配置模板,也能够做为bean实例。若只想把父bean做为模板,能够设置
的abstract属性为true,这样Spring将不会实例化这个Bean。
- 并非
元素里的全部属性都会被继承。好比autowire、abstract等。
也能够忽略父Bean的class属性,让子Bean指定本身的类,而共享相同的属性配置,但此时abstract必须设为true。
2.依赖Bean配置
- Spring容许用户经过depends-on属性设定Bean前置依赖的Bean,前置依赖的Bean会在本Bean实例化以前建立好。
若是前置依赖于多个Bean,则能够经过逗号、空格的方式配置Bean的名称。
五.bean的做用域
- 在Spring中,能够在
元素的scope属性里设置Bean的做用域。
默认状况下,Spring只为每一个在IOC容器里面声明的Bean建立惟一一个实例,整个IOC容器范围内都能共享该实例:全部后续的getBean()调用和Bean引用都将返回这个惟一的Bean实例。该做用域被称为singleton,它是全部bean的默认做用域。
singleton |
在SpringIOC容器中仅存在一个Bean实例,Bean以单实例的方式存在 |
prototype |
每次调用getBean()时都会返回一个新的实例 |
request |
每次HTTP请求都会建立一个新的Bean,该做用域仅适用于WebApplicationContext环境 |
session |
同一个HTTP session共享一个Bean,不一样的HTTP Session使用不一样的Bean。该做用域仅适用于WebApplicationContext环境。 |
globalSession |
通常用于protlet应用环境,该做用域仅适用于WebApplicationContext环境。 |
六.使用外部属性文件
1.在配置文件里配置Bean时,有时须要在Bean的配置里混入系统部署的细节信息(例如:文件路径,数据源配置信息等)。而这些部署细节实际上须要和Bean配置相分离。
2.Spring提供了一个PropertyPlaceholderConfigurer的BeanFactory后置处理器,这个处理器容许用户将Bean配置的部份内容外移到属性文件中。能够在Bean配置文件里使用形式为 ${var} 的变量,PropertyPlaceholderConfigurer从属性文件里加载属性,并使用这些属性来替换变量。
3.Spring还容许在属性文件中使用${propName},以实现属性直接的相互做用。
4.注册PropertyPlaceholderConfigurer
Spring2.0的配置方式:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties"></property>
</bean>
Spring2.5以后:可经过
元素简化:
-
中添加context Schema定义
- 在配置文件中加入以下配置
<context:property-placeholder location="classpath:db.properties" />
七.SpEL
1.Spring表达式语言(简称SpELl):是一个支持运行时查询和操做对象图的强大的表达式语言。
- 语法相似于EL:SpELl使用#{...}做为界定符,全部再打括号中的字符都被认为是SpEL
- SpEL为bean的属性进行动态赋值提供了便利。
- 经过SpELl能够实现:
- 经过bean的id对bean进行引用。
- 经过方法以及引用对象的中的属性
- 计算表达式的值
- 正则表达式的匹配
2.SpELl的字面量
- 字面量的表示
- 整数:
- 小数:
- 科学计数法:
- String可使用单引号或者双引号做为字符串的界定符号:
.
- booean:
3.引用Bean、属性和方法
- 应用其余对象
经过value属性和SpELl配置bean之间的关系
<property name="prefix" value="#{prefixGenerator}"/>
- 引用其余对象的属性
经过value属性和SpELl配置suffix属性值为另外一个Bean的suffix属性值
<property name="suffix" value="#{sequenceGenerator2.suffix}"/>
- 调用其余方法,还能够链式操做
经过value属性和SpELl配置suffix属性值为另外一个Bean的方法的返回值
<property name="suffix" value="#{sequenceGenerator2.toString()}"/>
方法的链式操做
<property name="count" value="#{sequenceGenerator2.toString().toUpperCase()}"/>
-调用静态方法或静态属性:经过T()调用一个类的静态方法,它将返回一个Class Object,而后再调用相应的方法或属性。
<property name="initValue" value="#{T(java.lang.Math).PI}"></property>
4. SpEL支持的运算符号
- 数学运算符:+,-,*,/,%,^:
- 加好还能够用做字符串的链接。
- 比较运算符:<,>,==,<=,>=,lt,gt,eq,le,ge
- 逻辑运算符:and,or,not,|
- if-else运算符:?:(ternary),?:(Elvis)
- if-else的变体
- 正则表达式:matches
八.Bean的生命周期
1.IOC容器中Bean的生命周期方法
- Spring IOC容器能够管理Bean的生命周期,Spring容许在Bean生命周期的特定点执行定制的任务。
- SpringIOC容器对Bean的生命周期进行管理的过程:
- 经过构造器或工厂方法建立Bean实例。
- 为Bean的属性设置值和对其余Bean的引用。
- 调用Bean的初始化方法。
- Bean可使用了。
- 当容器关闭了,调用Bean的销毁方法。
在Bean的声明里设置init-method和destroy-method属性,为Bean指定初始化和销毁方法。
2.建立Bean后置处理器
- Bean后置处理器容许在调用初始化方法先后对Bean进行额外的处理。
- Bean后置处理器对IOC容器里的全部Bean实例逐一处理,而非单一实例。其典型应用是:检查Bean属性的正确性或根据特定的标准更改Bean的属性。
对Bean后置处理器而言,须要实现BeanPostProcessor接口。在初始化方法被调用先后,Spring将把每一个Bean实例分别传递给上述接口的postProcessAfterInitialization()方法和postProcessBeforeInitialization()方法。
3.添加后置处理器后Bean的生命周期
SpringIOC容器对Bean的生命周期进行管理的过程:
- 经过构造器或工厂方法建立Bean实例。
- 为Bean的属性设置值和对其余Bean的引用。
- 将Bean实例传递给Bean后置处理器的postProcessBeforeInitialization()方法。
- 调用Bean的初始化方法。
- 将Bean的实例传递给Bean的后置处理器的postProcessAfterInitialization()方法。
- Bean能够正常使用了。
当容器关闭时,调用Bean的销毁方法。
4.经过调用静态工厂方法建立Bean
- 调用静态工厂方法建立Bean是将对象建立的过程封装到静态方法中。当客户端须要对象时,只须要简单地调用静态方法,而不用关心建立对象的细节。
要声明经过静态方法建立的Bean,须要在Bean的class属性里面这么拥有该工厂的方法的类,同时在factory-method属性里指定工厂方法的名称。最后使用
元素为该方法传递方法参数。
5.经过调用实例工厂方法建立Bean
- 实例工厂方法:将对象的建立过程封装到另一个对象实例的方法里。当客户端须要请求对象时,只须要简单的调用该实例方法而不须要关系对象的建立细节。
- 要声明经过实例工厂方法建立的Bean
- Spring中有两种类型的Bean,一种是普通Bean,另外一种是工厂Bean,即FactoryBean。
工厂Bean跟普通Bean不一样,其返回的对象不是指定类的一个实例,其返回的是该工厂Bean的getObject方法所返回的对象。
九.组件装配
1.在classpath中扫描组件
- 组件扫描:spring可以从classpath下自动扫描,侦测和实例化具备特定注解的组件。
- 特定组件包括:
- @Component:基本注解,标识了一个受Spring管理的组件。
- @Responsitory:标识持久层组件。
- @Service:标识服务层(业务层)组件。
- @Controller:标识表现出组件。
- 对于扫描到的组件,Spring有默认的命名策略:使用非限定类名,第一个字母小写。也能够在注解中经过value属性值标识组件的名称。
- 当在组件类上使用了特定的注解以后,还须要在Spring的配置文件声明
:
<context:component-scan base-package="com.desperado.helloworld" resource-pattern="autowire/*.class />
和
子节点支持多种类型的过滤表达式。
annotation |
com.desperado.XxxAnnotation |
全部标注了XXXAnnotation的类。该类型采用目标;类是否标注了某个注解进行过滤。 |
assinable |
com.desperado.XxxService |
s全部继承或扩展XXXService的类。该类型采用目标类是否继承或扩展某个特定类进行过滤。 |
aspectj |
com.desperado..*Service+ |
全部类名以Service结尾的类以及继承或扩展它们的类。该类型采用AspectJ表达式进行过滤 |
regex |
com.desperado.anno..* |
全部com.desperado.anno包下面的类。该类型采用正则表达式根据类的类名进行过滤。 |
custom |
com.desperado.XxxTypeFilter |
采用XXXTypeFilter经过代码的方式定义过滤规则。该类必须实现org.springframework.core.type.TypeFilter接口 |
3.使用@Resource或@Inject自动装配Bean

十一.整个多个配置文件
Spring容许经过
将多个配置文件引入到一个文件中,进行配置文件的集成。这样在启动Spring容器时,仅须要指定这个合并好的配置文件就能够。
import元素的resource属性支持Spring的标准的路径资源
classpath: |
classpath:spring-mvc.xml |
从类路径下加载资源,classpath:和classpath:/是等价的 |
file: |
file:/conf/security/spirng-shiro.xml |
从文件系统目录中装载资源,可采用绝对或相对路径 |
http:// |
http:///www.desperado.com/resource/beans.xml |
从web服务器中加载资源 |
ftp:// |
ftp://www.desperado.com/resource/beans.xml |
从FTP服务器中加载资源。 |