Spring’s Story
1.1 下载地址:http://repo.springsource.org/libs-release-local/org/springframework/spring/
============================================================
1.2 背景知识
Spring为企业应用的开发提供一个轻量级的解决方案
该解决方案包括:基于依赖注入的核心机制,基于AOP的声明式事务管理与多种持久层技术的整合等
依赖注入,是Spring的核心机制,可以使Spring的bean以配置文件组织在一起,而不是以硬编码的方式耦合在一起
因为某些历史原因,依赖注入还有一种称呼:控制反转,其含义完全相同
Rod Johnson 2002年编写《Expert one on one J2EE design and development》一书,并在2003年时对其进一步改造和扩充,Spring诞生了
对于Web应用,只要将spring的相关jar文件复制到WEB-INF/lib中,该应用就可以利用Spring框架了
============================================================
1.3 设计模式
Spring使用了两种设计模式:工厂模式和单例模式
工厂模式可将Java对象的调用者从被调用者的实现逻辑中分离出来,调用者只需关心被调用者必须满足的规则(接口),而不必关心实例的具体实现过程
这是面向接口编程的优势,工厂模式能降低程序的耦合,避免所有的类以硬编码方式糯合在一起
Spring容器是实例化和管理全部bean的工厂,默认将所有的bean设置成单例模式,即对所有相同idbean请求都将返回同一个共享实例
因此,大大降低了Java对象在创建和销毁时的系统开销,单例模式提高系统的性能。
Spring使用配置文件管理所有的bean,其配置文件中bean由Spring工厂负责生成和管理
由于厂无须多个实例,因此工厂应该采用单态模式设计。其中Spring的上下文,也就是Spring工厂,已被设计成单态的
Spring工厂提供了创建bean的功能,还提供对bean生命周期的管理功能,更重要的是还有管理bean与bean之间的依赖关系的功能
============================================================
1.4 依赖注入
在依赖注入的模式下,创建被调用者的工作不再由调用者来完成,而是由Spring容器来完成,然后注入调用者
根据不同的注入形式,依赖注入又分为设值依赖注入和构造依赖注入
在设置注入时,Spring会自动接管每个bean定义里的property元素定义,并调用对应的setter方法为程序注入属性值,
这种注入方式简单、直观,因而被大量使用
构造注入则是通过构造函数来完成依赖关系的设定,当对注入顺序有要求时、依赖关系无须变化时使用其更好,
因为构造注入更符合高内聚的原则,但一般情况下建议采用以设值注入为主,构造注入为辅的注入策略
============================================================
1.5 beanFactory和bean
1.5.1 Spring容器
Spring容器本质上是一个高级工厂,负责产生bean实例,并管理singleton bean生命周期。
bean是Spring管理的基本单位,在Spring的J2EE应用中,所有的组件都是bean,包括数据源、HibernateSessionFactory及事务管理器等
容器通常有两种表现形式::BeanFactory可和ApplicationContext,这两个接口的实例也被称为Spring上下文
bean是通过AppliactionContext提供访问的,因为AppliactionContext是BeanFactory的子接口,提供比BeanFactory更多的功能
BeanFactory接口包含如下的基本方法。
•public boolean containsBean(String name):判断Spring容器是否包含id是name的bean
•public Object getBean(String name):返回容器id是name的bean
•public Object getBean(String name,Class requiredType):返回容器中id是name并且类型为requiredType的bean
•public Class getType(String name):返回容器中id是name的bean的类型
我们使用getBean方法,即可获得指定bean的引用
Spring的配置用XML文件设置,因此,在创建BeanFactory实例时,我们提供XML文件作为参数,并使用如下两个实现类:
•FileSystemXmlApplicationContext:以指定路径的XML配置文件创建ApplicationContext
•ClassPathXmlApplicationContext:CLASSPATH路径下的XML配置文件创建ApplicationContext
ClassPathXmlApplicationContext appContext = new ClassPathXrnlApplicationContext(" applicationContext.xml","service.xml"});
//ApplicationContext是BeanFactory 的子接口,支持强制类型转换 BeanFactory factory = (BeanFactory) appContext;
1.5.2 bean定义
beans元素是Spring配置文件的根元素,bean元素是beans元素的子元素,beans元素可以包含多个bean元素
在定义bean时,通常(非使用实例工厂时)必须指定以下两个属性:
id:容器对bean管理、访问及该bean的依赖关系,都通过该属性完成。
class:指定具体实现类,这里不能是接口,Spring会直接使用new关键字创建该bean的实例
Spring中的bean是Java实例与Java组件,而传统Java应用中的bean通常作为model,用来封装值对象在各层之间的传递
传统JavaBean也可作为普通的Spring的bean,可接受Spring管理,Spring甚至不要求bean为每个属性都提供对应的getter和setter方法
区别:1用法不同-任何组件都可称为bean 2写法不同-只需提供setter方法 3生命周期不同-由Spring管理其生命周期
1.5.3 bean行为
bean在Spring的容器中有两种基本行为:单例singleton和非单例prototype --request\session\application
通常我们将Web应用的控制器bean(即Action)配置成非单例,
此时,Spring容器使用new键字创建bean实例,一旦创建成功,容器不再跟踪实例,也不会维护bean实例的状态
对应的,若是单例,则Spring容器还要负责跟踪bean实例的状态,维护bean实例的生命周期
//Spring容器会自动预初始化所有的singleton的bean,对于prototype则不会
1.5.4 bean创建
通常用一下3种方法:
1 调用构造器创建一个bean实例
2 BeanFactory调用某个类的静态工厂方法创建bean
3 BeanFactory调用实例工厂方法创建bean
1是最普通的,此时必须指定class属性,创建过程是这样的:
1创建BeanFactory实例 2调用Chinese类的默认构造器创建默认实例
3根据配置文件注入依赖关系:先实例化依赖bean,然后通过setter方法将依赖bean注入 4返回一个完整的bean实例
当使用静态工厂时,必须指定class和factory-method属性
当使用实例工厂时,使用factory-bean 确定工厂bean; 使用 factory-method确定工厂方法:使用constructor-arg确定工厂方法的参数
1.5.5 bean依赖
如果实例A调用实例B的方法,可称为A依赖于B。在传统的系统中,如果A依赖于B,则负责创建B,或者定位B工厂,通过B工厂获得实例。
而依赖注入却与此相反,如果A依赖于B,则实例A不再由负责生成B,而由容器负责生成B,并注入给实例A
配置依赖 :依赖通常可以接受如下元素指定值:
•value•ref•bean•list,set,map,以及props
此外还可以注入另一个实例的属性值、静态域值和方法返回值。
用depends-on参数可以优先强制初始化依赖的bean,而不是先初始化自己
有时也可以使用自动装配:no|default\byName\byType\constructor
1.5.6 bean周期
注入依赖关系之后:1 调用方法 init-method 2 使用接口 InitializingBean
即将销毁bean之前:1 调用方法 destory-method 2 使用接口 DisposableBean
1.5.7 bean同步
单例依赖模板时,模板更新后,单例的依赖不能得到即时更新,此时会产生不同步的现象
解决方法:使用方法注入1 public abstract XXX createXxx(); 2 <lookup-method name="createXxx" bean="XXX" />
1.5.8 bean继承
Spring中的bean的继承是对象与对象之间的参数传递,而Java中的继承是类与类之间的关系
父类可以使用abstract,子类使用parent属性指定父类
1.5.9 bean后处理器与spring后处理器
处理器在其对象实例化结束后,对对象进行额外的处理。
bean后处理器思想可以参考1.5.6,Spring提供很多容器后处理器,其思想与下面2种类似:
属性占位符,读取类路径下的jdbc.properties文件
<context:property-placeholder location="classpath:jdbc.properties"/> 对应格式 jdbc.xxx=xxx 取值 value="${ jbdc.xxx }"
<context:property-override location="classpath:jdbc.properties"/> 对应格式:beanName.property=value
通过容器后处理器,可将配置文件分割成多个属性文件,从而降低修改配置文件的风险
1.5.10 bean回调\别名\导入
回调:bean实现BeanNameAware接口...
别名:<alias name="user" alias="user1"/>
导入:<import resource="alias.xml"/>
============================================================