本文参考了李刚的《轻量级Java EE企业应用实践》
1.使用Spring框架时,必须使用Spring Core Container(即Spring容器)。Spring Core Container主要由org.springframework.core、org.springframework.beans、org.springframework.context和org.springframework.expression四个包及其子包组成,主要提供Spring IOC容器支持。
Spring框架的核心功能有两个:
1)Spring容器作为超级大工厂,负责创建。管理所有的java对象,这些Java对象被称为Bean.
2)Spring容器管理容器中Bean之间的依赖关系,Spring使用一种被称为“依赖注入”的方式来管理Bean之间的依赖关系。
依赖注入的好处是:Java EE应用中的各种组件不需要以硬编码方式耦合在一起,甚至无需使用工厂模式,是一种优秀的解耦方式)
2.使用Spring管理bean
Spring核心容器就是一个超级大工厂,所有的对象(包括数据源、Hibernate SessionFactory等基础性资源)都会被当成Spring核心容器管理的对象--Spring把容器中的一切对象统称为Bean。
对于Spring框架而言,一切java对象都是Bean。
1)bean的定义
对于bean的管理,Spring提供了两种方式:xml形式;注解形式。
* 在xml文件中 注入bean。如:
注意:如果采用xml注入bean,则在Person类中,需要Axe的setter方法(getter方法不是必须的)。
子元素通常用于作为 元素的子元素,它驱动Spring在底层以反射执行一次setter方法。其中 的name属性值作为执行哪个setter方法,而value或ref决定执行setter方法的传入类型。
*注解形式
@Component:标注一个普通的Spring Bean类。
@Controller: 标注一个控制器组件类。
@Service: 标注一个DAO组件类。
@Responsitory; 标注一个DAO组件类。
注意:使用注解,可以明显减少XMl中bean的配置,比较适用于小型的应用。对于大型应用,在ApplicationContext启动时,bean就会被加载。对于大型应用,尤其是在程序分模块时,可能只需加载相关的bean;如果使用注解,不利于根据 模块来控制bean的生命周期。
2)bean的创建、加载。 Spring有两个核心接口:BeanFactory和ApplicationContext,其中ApplicationContext是BeanFactory的子接口。在基于Spring的JavaEE应用中,所有的组件都被当成Bean处理,包括数据源、Hibernate的SessionFactory、事务管理器等。
BeanFactory接口提供了几个基本方法:
*boolean containsBean(String name)
* T getBean(Class requiredType ):获取Spring容器中属于requiredType类型的、唯一的Bean实例。
*Object getbean(String name):返回容器中id为name的Bean实例的类型。
*Class> getType(Stirng name):返回容器中id为name的Bean实例的类型。
通常使用Spring容器的接口ApplicationContext接口来访问容器中的Bean。该接口还有额外的功能:
*ApplicationContext默认会预初始化所有的singletion Bean,也可通过配置取消预初始化。
*ApplicationContext集成MessageSource接口,因此提供国际化支持。
*资源访问,比如访问URL和文件。
*事件机制:使用了观察者设计模式,通过ApplicationEvent类和ApplicationListener接口,可以实现 ApplicationContext的事件处理。主程序使用ApplicationContext的publishEvent()来触发时间。
*同时加载多个配置文件。
*以声明式方式启动并创建Spring容器。
该接口有以下几个实现类:
*ClassPathXmlApplicationContext:从类加载路径下搜索配置文件,并根据配置文件来创建Spring容器。
*FileSystemXmlApplicationContext:从文件系统的相对路径或者绝对路径下去搜索配置文件,并根据配置文件来创建Spring容器。
*AnnotationConfigApplicationContext。
*在web应用中,通常有XmlWebApplicationContext、AnnotationConfigWebApplicationContext两个类。
在写单元测试时,要使用Application进行加载bean。如:
ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
Person p=ctx.getBean("person",Person.class);或者 Person p=(Person)ctx.getBean("person");
如果这段代码报错,首先看是否是加载context出错(如路径问题、xml文件是否引入context的命名空间);其次看bean是否存在。
注意:对于bean,在代码中不能进行new。原因是bean是由Spring容器进行创建、管理的,在ApplicationContext容器初始化完成后,bean就被加载了。Spring管理的bean不支持在代码中直接进行new。
当系统创建ApplicationContext容器时,默认会初始化所有的singleton Bean.当ApplicationContext容器初始化完成后,容器会自动初始化所有的singleton Bean,包括调用构造器创建读该Bean的示例,并根据>元素执行setter方法。这意味着:系统前期创建Applicationcontext时将有较大的系统开销,但一旦ApplicationContext初始化完成,程序后面获取singleton Bean实例时将拥有较好的性能。
BeanFactory与Application实例化容器中Bean的时机不同:前者等到程序需要Bean实例时才创建Bean;而后者在容器创建ApplicationContext实例时,会与初始化容器中所有的singleton Bean。因此,ApplicationContext实例化过程比BeanFactory实例化过程的时间和内存开销大,但可以在容器初始化阶段就检验处配置错误。
3)容器中Bean的生命周期
*对于singleleton作用域的bean,Spring可以精确地知道该Bean何时被创建、何时被初始化完成、容器何时准备销毁该Bean实例。
*对于prototype作用域的bean,Spring容器仅仅负责创建。
3.注入的方式
依赖注入通常有两种注入 :设值注入即通过setter注入;构造注入。
1)设值注入
scope="prototype">
在开发中,建议以设值注入为主,构造注入为辅的注入策略(在构造器中决定依赖关系的注入顺序并且依赖关系无需变化,如DataSource的注入)。
4.对注入依赖、控制反转的理解
使用Spring框架之后,调用者无需主动获取被依赖对象,调用者只要被动接受Spring容器为调用者的成员变量赋值即可(只要配置一个
从Spring容器的角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量--相当于为调用者注入它依赖的实例,因此Martine Fowler将这种形式称为依赖注入。
使用Spring框架之后的两个主要改变是:
1) 程序无需使用new调用构造器去创建对象。所有的Java对象都可以交给Spring容器去创建。
2)当调用者需要调用被依赖对象的方法时,调用者无需主动获取被依赖对象,只要等到Spring容器注入即可。
使用Spring Ioc容器的三个基本要点:
1)应用程序的各组件面向接口编程。面向接口编程可以将组建之间的耦合关系提升到接口层析,从而有利于项目后期的扩展。
2)应用程序的各组件不再由程序主动创建,而是由Spring容器来负责产生并初始化。
3)Spring采用配置文件或注解来管理Bean的实现类、依赖关系,Spring容器则根据配置文件或注解,利用反射来创建实例,并为之注入依赖关系。
Spring管理接受设值注入的Bean时, 应提供对应的setter方法,并不要求提供对应的getter方法。传统的JavaBean作为值对象传递,不接受任何容器管理生命周期,而Spring中的Bean由Spring管理其生命周期行为;传统的JavaBean更多的是作为值对象传递参数;Spring的bean用处几乎无所不包,任何应用组件都被成为Bean。
Spring支持3种方式创建Bean:
1)调用构造器创建Bean。(使用constructor-arg子元素)
2) 调用静态工厂方法创建Bean。
3)调用实例工厂方法创建Bean。
5.Spring的AOP
AOP:面向切面编程。Spring4.0的AOP与AspectJ进行了很好的继承。
6.Spring的事务
Spring事务策略是通过PlatformTransactionManager接口体现的,该接口是Spring事务策略的核心。该接口的源代码如下:
public interface PlatformTransactionManager{
//平台无关的获得事务的方法
TransactionStatus getTransaction(TransactionDefination definition)throws TransactionException;
//平台无关的事务提交方法
void commit(TransactionStatus status)throws TransactionException;
//平台无关的事务回滚方法
void rollback(TransactionStatus status)throws TransactionException;}
使用JDBC数据源的局部事务管理器时,配置如下: