第一章:Spring框架的由来
整个Spring框架构建在Core核心模块之上,这是整个框架的基础。在该模块中,提供了IoC(Inversion of Control控制反转)容器的实现。在这个基础之上,是AOP,JEE,MVC等框架。
AOP(Aspect Oriented Programming,面向切面编程)框架可以以AOP的形式增强各POJO(Plain Ordinary Java Object,简单的Java对象)的能力,进而补足OPP/OOSD之缺憾。该框架符合AOP Alliance规范,采用Proxy模式构建,与IoC容器结合。在AOP模块之上,提供了完备的数据访问和事务管理的抽象和集成服务。
Spring框架另为我们提供了针对Java EE的集成服务。
最后是Web模块,Spring框架提供了一套自己的Web MVC框架。
第二章:IoC的基本概念
IoC主要有三种依赖注入的方式:
(1)接口注入:不提倡,基本处于退役状态。
(2)构造方法注入:这种注入方式的优点就是,对象在构造完成之后,已经进入就绪状态,可以马上使用。缺点是,当依赖对象比较多时,构造方法参数列表会较长,通过反射构造对象时,对相同类型的参数处理会比较困难,维护和使用比较麻烦。构造方法无法被继承,无法设置默认值。
(3)setter方法注入:在描述性上要比构造方法注入好一些,另外setter方法可以被继承,允许设置默认值,有良好的IDE(Integrated Development Environment,集成开发环境)支持。缺点是对象无法在构造完成后马上进入就绪状态。
第四章:IoC容器之BeanFactory
(1)外部配置文件方式
现在有Properties文件格式和XML文件格式(主要),注解方式(Spring2.5,Java5以上支持)。
<?xml version="1.0" encoding="UTF-8"?>
<!-- 指定Spring配置文件的Schema信息 -->
<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-3.0.xsd" >
<!-- 它拥有以下的属性
default-lazy-init:其值可以指定true或false,默认为false,标志是否对所有的bean延迟初始化。
default-autowire:可以取值为no,byName,byType,constructor,autodetect,默认为no,标志全体bean使用哪一种默认绑定方式。
default-dependency-chech:可以取值为none,objects,simple以及all,默认为none即不做检查。
default-init-method:如果所管辖的隱按照某种规则,都有同样名称的初始化方法的话,可以在这里统一指定这个初始化方法名,而不用在每一个bean上都重复单独指定。
default-destroy-method:如果所管辖的bean有按照某种规则使用了相同名称的对象销毁方法,可以通过这个属性统一指定
-->
<!-- 同级标签
<description>:描述信息
<impor>:引用所依赖的配置文件
<alias>:为bean起别名
-->
<bean id="djNewListener" name="/news/djnewslistener,dowJon" class="..impl.DowJoneNewsListener">
<!-- name可以为bean指定别名,可以使用id不能使用的字符,比如/而且还可以通过逗号,空格分割指定多个name,它的使用和alias很相似 -->
<!-- 在使用构造方法注入时,可以采用以下方式,但这种方式往往存在指代不明的情况,不适合多参数构造 -->
<constructor-arg ref="djNewsListener"/>
<!-- 或 -->
<constructor-arg >
<ref bean=djNewsPersister""/>
</constructor-arg>
<!-- ref 指向的属性有local(指向同一配置文件下的对象定义名称),parent(指向当前容器的父容器的对象引用),bean(支持以上两种类型)-->
<!-- 在使用构造方法注入时,为了区别构造函数的多态,需要给参数限定类型 -->
<constructor-arg type="int"><value>11111</value></constructor-arg>
<!-- 在使用构造方法注入时,为了满足构造函数存在多参数的情况,需用以下方式,以index的值标示其为构造函数的第几个参数 -->
<constructor-arg index="1" value="11111"/>
<constructor-arg index="0" value="222222"/>
<!-- 以上三种构造方法应该是不能混用的 -->
<!--使用setter方法注入时 ,该方式可以构造方法混用-->
<property name="dependency" value="123"/>
</bean>
<bean id="djNewsListener" class="..impl.djNewsListener">
<property name="innerbean">
<bean class="..impl.DowJoneaNewsListener"></bean><!-- 内部bean,可省略id -->
</property>
<property name="nulltest">
<null/>
</property>
<!-- 另可以配制list,set,map,props对象,但考虑到都是多层嵌套,容易出错,不推荐使用 -->
</bean>
<bean id="djNewsListener" class="..impl.djNewsListener" depends-on="djNewListener">
<!-- depends-on可在初始该类前初始化diNewListener -->
</bean>
<bean id="ListenerChild" class="..impl.ListenerChild" parent="superNewsProvider">
<!-- 通过parent属性可继承父类定义的默认值 -->
</bean>
<bean id="scopetest" class="..impl.scopetest" singleton="true">
<!-- 或者 <bean id="scopetest" class="..impl.scopetest" scope="singleton"-->
<!-- 各属性含意
singleton:在一个容器中只存在一个共享实例,所有对该类型bean的依赖都引用这一单一实例。存活时间从容器启动到它第一次被请求而实例化开始,
只要容器不销毁或者退出,该实例就会一直存活
prototype:容器在接到该类型对象的请求的时候,每次都重新生成一个新的对象实例给请求方。
request:为每个HTTP请求创建一个全新的Request-Processor对象借当前请求使用,当请求结束后,该对象实例的生命周期即告结束。可视为prototype特例。
session:为每个独立的session创建属于自己的全新的UserPreferences对象实例。与request相比,实例可能存活更长的时间。
global session:基于portlet的Web程序才有意义,它映射到portlet的global范围的session。
-->
</bean>
<bean id="factoryBeantest" class="..impl.factoryBeantest" factory-method="getInstance">
<!-- 调用工厂方法,返回的是getInstance方法中生成的对象,现在采用的是静态构造方法,另可以采用非静态方式
如果一定要取得FactoryBean
-->
<constructor-arg index="0"><value>123456</value></constructor-arg>
</bean>
</beans>
以上为Bean标签的一些基本使用。
(2)bean的一生
首先BeanDefinationReader完成定义信息的解析,解析出来的每个Bean的信息会创建一个BeanDefinition保存,Beandefinition实例与受管对象一一对应。BeanDefinitionRegestry完成IOC容器注册。
BeanFactory定义对bean的操作。其中getbean方法开始Bean实例化活动(初次调用),之后的调用视scope设定值返回初次调用生成的实例或生成新的实例。这其中会采用策略模式来决定采用何种方式化bean。BeanWapper用来设置对象属性值。BeanPostProcessor有两个方法,前者在实例化及依赖注入完成后、在任何初始化代码(比如配置文件中的init-method)调用之前调用;后者在初始化代码调用之后调用,这两个方法用来添加一些自己的逻辑处理。
第五章 Spring IoC容器ApplicationContext
(1)统一资源加载策略
Spring框架内部使用org.springframework.core.io.Resource接口作为所有资源的抽象和访问接口,有以下实现类:
ByteArrayResource:将字节(byte)数组提供的数据作为一种资源进行封装,如果通过InputStream形式试问该类型的资源,该实现会根据字节数组的数据,构造相应的ByteArrayInputStream并返回。
ClassPathResource:该实现从java应用程序的classpath中加载具体资源并进行封装,可以使用指定的类加载器(ClassLoader)或者给定的类进行资源加载。
FileSystemResource:对java.io.File类型的封闭。
UrlResource:通过java.net.URL进行具体资源查找定位的实现类,内部委派URL进行具体的资源操作。
InputStreamResource:将给定的InputStream视为一种资源的Resource实现类,较为少用。
以上为资源的实现,如何查找,定位这些资源,则是ResourceLoader的职责所在了。但是ResourceLoader每次只能根据资源路径返回确定的单个Resource实例,ResorcePatternResolver则可以根据指定的资源路径匹配模式,返回多个实例。
而对于ApplicationContext,从它的继承关系,可以得出它会完成如下功能:
1,扮演ResouceLoader角色
2,ResourceLoader类型的注入
3,Resource类型的注入
4,特定情况下,ApplicationContext的Resource加载行为。这一功能主要资源路径中的扩展协议前缀中的classpath:和classpath*:。(注意,即使在FileSystemXmlApplicationContext实例化启动时,通过classpath:前缀强制让它从Classpath中加载bean定义文件,但这也仅限于容器的实例化并加载bean定义文件这个特定阶段,容器实例化后,还是会默认从文件系统中加载资源。)
(2)容器内部事件发布
Spring的ApplicationContext容器内部允许以org.springframework.context.ApplicationEvent形式发布事件。窗口内部注册的org.springframework.context.ApplicationListener类型的bean定义会被ApplicationContext窗口自动识别,它们负责监听容器内发布的所有ApplicationEvent类型的事件。
默认情况下,Spring提供了ApplicationEvent三个实现:
ContextClosedEvent:ApplictionContext容器在即将关闭的时候发布事件类型。
ContextRefershedEvent:在初始化或刷新的时候发布事件类型。
RequestHandledEvent:Web表示处理后发布的事件。
担任事件发布者角色的是ApplicationContext容器,不过它把个体实现类在实现事件的发布和事件监听器注册方面的活转包给了ApplicationEventMulticaster接口,它接下来做的工作如下图所示: