Spring详解

传统代码严重依赖于实现而不是接口。 如:

public class OneAction(){        

private UserDao dao = new UserJdbcDao();//严重依赖        

privatte UserHibernateDao  dao = new UserHibernateDao();

}

非常难以扩展,必须修改原代码。 数据库事务的控制与我们的代码交织在一块,难以维护。 或是数据库事务的代码粒度不够细。不能明确标明何种异常应该回滚事务。 如在这前的OSIV模式中,即使不是SQLException异常也会回滚事务。这就不够细粒度。

Spring 轻量、企业、对象容器、框架。

Spring是一个开源框架,是为了解决企业应用开发的复杂性而创建的。 Spring在软件开发中所占的位置是承上启下。 目的:解决企业应用开发的复杂性。 功能:使用基本的SpringBean代替EJB,并提供了更多的企业应用功能 。 范围:任何Java应用 。 简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

Spring简介:

轻量——从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。

非侵入 ——在应用中,一般不需要引用springjar包里的类。

控制反转——Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,某一接口的具体实现类的选择控制权从调用类中移除,转交给第三方裁决。

面向切面——Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务()管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责其它的系统级关注点,例如日志或事务支持。

Spring即是一个容器又是一个框架。

容器——Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype),你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。

框架——Spring提供了很多基础的与业务逻辑无关的功能,比如:事务管理、持久化框架集成等等,使用Spring框架,开发人员可以专注于业务逻辑开发,这个意义上讲它是一个框架。

为何要使用Spring?

至少在我看来,在项目中引入spring立即可以带来下面的好处 降低组件之间的耦合度,实现软件各层之间的解耦。      

可以使用容器提供的众多服务,如:事务管理服务、消息服务等等。当我们使用容器管理事务时,开发人员就不再需要手工控制事务.也不需处理复杂的事务传播。

容器提供单例模式支持,开发人员不再需要自己编写实现代码。

容器提供了AOP技术,利用它很容易实现如权限拦截、运行期监控等功能。

容器提供的众多辅作类,使用这些类能够加快应用的开发,如: JdbcTemplate、 HibernateTemplate。

Spring对于主流的应用框架提供了集成支持,如:集成Hibernate、JPA、Struts等,这样更便于应用的开发。

Spring作为容器如何管理你的类

Spring提供了两个类来管理系统中的类, 调用这两个类的某些方法即可以获取到被容器管理的类。 这两个类是:BeanFactory和ApplicationContext. 被Spring管理的不仅是JavaBean,可是任意的类,我们称它们为SpringBean。

Spring的包结构

Spring2.5的包结构。

支持JDK1.4。不支持泛型。必须进行强制类型转换。

Spring3.0的包结构。

Jdk1.5以上。 支持根据BeanID获取Bean实例,支持泛型。

支持根据类名-接口名获取实例。

支持表达式语言。

#{…} 支持新的线程池。

直接支持任务调度。

Spring3.x提供的Jar包说明

spring-context.jar:提供IoC高级功能,JNDI、EJB的支持等

spring-aop.jar:Spring的AOP框架

spring-dao.jar:提供了对数据库的访问抽象,提供了对JDBC和数据库事务的支持

spring-orm.jar:提供了对Hibernate, JDO, iBATIS和OJB的支持

spring-web.jar:提供了对web的支持

spring-webmvc.jar:Spring自己的Web框架

spring-mock.jar:提供了通过Mock方式进行测试的包

org.springframework.beans所有应用都要用到的,它包含访问配置文件、创建和管理bean,以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有类 org.springframework.core 包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心

org.springframework.asm  Spring独立的asm程序

org.springframework.expression  Spring表达式语言 org.springframework.context.support  Spring提供在基础IoC功能上的扩展服务,此外还提供许多企业级服务的支持,如邮件服务、任务调度、JNDI定位、EJB集成、远程访问、缓存以及各种视图层框架的封装等

commons-logging  Spring日志功能

Spring的两个重要容器类

BeanFactory还是(VS) ApplicationContext.

ApplicationContext是BeanFactory的子接口。

BeanFactory通常称为Bean容器。

ApplicationContext通常称为应用上下文。它的功能要多于BeanFactory,如它可以加载外部的资源文件、可以自动进行AOP切面、可以识别自动代理的的类、可以识别用于监听Bean创建的类等。

-以下是使用ApplicationContext的示例:

通过BeanFactory读取xml文件获取Bean:

理解IoC和DI:

IoC:(Inversion of Control,控制反转)控制反转就是应用程序本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责。这样控制权就由应用程序本身转移到了外部容器,控制权的转移就是所谓的反转。

依赖注入(Dependency Injection):就是在运行期,由外部容器动态的将依赖对象注入到组件中 。 或是在运行期,由外部容器决定具体执行的类代码。

//手工注入方式:

public class PersonServiceBean {      

private PersonDao personDao = new PersonDaoBean();      

public void save(Person person){            

personDao.save(person);      

}

}

PersonDaoBean 是在应用内部创建及维护的。如果需要扩展或是修改,就必须要修改应用程序本身的源代码,这不符合OC原则。OC原则是指:OpenClose原则,即开闭原则。是指对修改关闭,对扩展开放。见:<Java与模式>第四章。

理解依赖注入(Dependency Injection)

当我们把依赖对象交给外部容器负责创建,那么PersonServiceBean 类可以改成如下:

public class PersonServiceBean {      

private PersonDao personDao ;     //通过构造器参数,让容器把创建好的依赖对象注入进PersonServiceBean,当然也可以使用setter方法进行注入。    

 public PersonServiceBean(PersonDao personDao){        

 this.personDao=personDao;    

 }          

public void save(Person person){            

personDao.save(person);    

 }

}

所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中。

控制反转-让你类依赖接口而不是实际类, 在运行期间,由外部容器决定具体要执行的类:

配置你的Spring Bean:

由Spring容器管理所有Java类.

声明Bean.

构造器注入和setter注入。

装配Bean,注入List,Map,Set,Array,注入其他Bean.

自动装配。

控制Bean的创建和销毁。

Spring提供了两种容器的实现: (前面已经说过)

1、Bean工厂,由BeanFactory定义。是最简单的容器。

2、应用上下文,由ApplicationContext定义,建立在Bean工厂之上,提供了系统构架服务,如从属性文件中读取文本信息,向有关的事件监听器发布事件等。同时ApplicationContext是BeanFactory的子类。 两个容器都可以调用Bean的私有/公有构造方法实例化一个类。 它们两个的区别: BeanFactory只有当需要获取一个Bean时才会去创建这个Bean的实例。 ApplicationContext在启动时一次初始化所有Bean的实例、可以自动识别代理自动代理类、可以识别自动加载Bean等。

BeanFactory的实现类-XmlBeanFactory:

XmlBeanFactory是BeanFactory的子类。

XmlBeanFactory用于读取beans.xml的配置文件,它接收一个 Resource类的实现: 比较常用的资源定义为:

ClassPathResource - 从classpath中读取

FileSystemResource -从文件系统中读取

ServletContextResource - 必须要在web环境下使用

ApplicationContext

BeanFactory对于简单应用来说,已经非常好用。但为了获取Spring框架强大的功能,你需要使用Spring的高级容器--应用上下文。

ApplicationContext的实现类为:

ClassPathXmlApplicationContext

FileSystemXmlApplicationContext

XmlWebApplicationContext – 需要Spring-web包的支持。

工具类:WebApplicationContextUtils用于在Web环境下获取容器。

Bean的装配:

通过构造器注入。 - Inverse of Control (Dependens Injection)

DI 是指在类中声明一个类型的接口,在配置文件中由外部的容器在运行时设置具体的值。

Class person{       private String name = “wj”      set…get….. }

<bean id=p class=“…”>

<proprety name=“name=“ value=“ddd/.”>

通过setter方法注入。

给Bean注入集合。

给Bean注入其他Bean.

自动装配。

通过构造器注入:  (注入值类型和引用类型)

通过属性注入:  (注入值类型和引用类型均可)

注入集合:

注入null值:

Bean的自动装配:

自动装配是指Spring根据指定的自动模式查找相关属性并自动装配。

Spring提供四种Bean的自动装配类型:

byName-试图在容器中查找与属性名称相同的Bean的id,如果没有找到,则此属性装配不成功。

byType-试图在容器中查询与属性类型相同的Bean,如果没有找到,则此属性装配不成功。如果找多个类型相符的Bean则会抛出UnsatisfiedDependencyException异常。

Constructor-查找与自动装配的Bean的构造参数一致的一个或多个Bean。如果存在不确定的Bean或是构造,将会抛出一个异常。

Autodetect -首先使用constructor来装配,然后再尝试用byType来装配。注意,到了spring3.0中,此项已经不再支持。

byName自动装配:

开发步骤:

开发Address类及接口IAddress。

开发Person类并声明Iaddress(接口)成员变量。

在配置文件中通过byName自动装配。

说明:如果没有找到合适的名称匹配,则属性配置不成功,将返回null值。(不会抛出异常)

byType自动装配:

说明:以下例当中,如果出现两个相同类型的属性则会在装配时抛出异常。

以下代码将会抛出一个异常。因为同时存在两个类型相同的Bean。

何时使用自动装配:

尽管自动装配给我们带来了很多方便,但同时也会带来很多问题。

如:按byType装配,不能在容器中多次声明一个Bean.

目前自动装配最大的缺点是缺乏透明。

由于自动装配隐藏了很多细节,所以一般情况下,我们不建议使用自动装配。

控制Bean的创建:

1、Bean的范围。

2、利用工厂方法创建Bean.

3、初始化和销毁Bean.

Bean的范围:

默认情况下,所有Spring的Bean都是单一的。即单例。

Bean的属性scope属性决定生成bean的方式:

Singleton – 单例,默认值 。

Prototype – 每一次请求创建一个新的实例。

Request – 在web容器中,每一个request创建一个。

Session – 在web容器中,第一个会话创建一个实例。 Global – session – Http会话,在portlet上才会有效。

利用工厂方法来创建Bean:

在某些情况下,如果你希望通过工厂方法来获取Bean的实例。则可以提供一个factory-method方法。 在创建之前,你可以在工厂方法中实现一些其他的细节。

一般情况下,工厂方法返回当前类的实例或是子类的实例。

初始化和销毁Bean:

在bean元素中,定义init-method和destory-method属性,可设置初始化方法和销毁方法。需要注意的是:如果scope属性为prototype则不受spring缓存的控制,destory方法也将不会执行。所以,如果希望由spring去调用销毁方法,则不能使用prototype类型的范围。

调用销毁方法:

如果需要Spring显示的去调用销毁方法,则必须销毁整个Spring容器,即关闭或是销毁BeanFactory或ApplicationContext。

上面两个接口中没有定义关闭方法,必须使用它们的子类才可以关闭容器。

容器的关闭,一般情况下不应由程序代码管理,应该交给第三方容器,如tomcat.

高级Bean装配:

父子Bean。

使用Spring的特殊Bean.

引用外部的资源文件。

声明父Bean和子Bean:

创建一个类来扩展另一个类,是面向对像的基础之一。

在Spring中,声明的两个Bean即使在实际类上没有继承关系,也是可以实现继承的。 S

pring的Bean为我们提供了两个属性可以实现继承。

Parent – 用于指明继承的Bean,类似于extends关键字。

Abstract - true|false. - 声明一个Bean为抽象Bean,使用了abstract关键字的类,不会被Spring容器实例化。

父子Bean示例:

1、我们首先声明了一个抽象类。

2、并在配置文件中使用了此类,和使用了 Abstract关键字。

父子Bean需要注意的问题:

在父Bean中定义的属性必须要在子Bean中出现。如果子Bean中没有定义相关属性,将会导致容器初始化失败。

使用Spring的特殊Bean

Spring容器在多大数情况下,会平等的对待所有Bean.

但有些Bean有特殊的任务,通过实现Spring的某些接口,可以将某些Bean当成Spring容器的一部分。

利用这些特殊的Bean我们可以:

对bean进行后处理,介入Bean的创建。

从外部资源文件加载信息。

让Bean了解容器。

配置属性的外在化:-经常用于数据连接

PropertyPlaceholderConfigurer类用于加载外部的资源文件。

<bean>    

<property name=“locations”>        

<list>          

<value></value>        

</list>

示例:使用外部的资源文件连接数据库的示例

引入外部的资源文件。

配置简单数据源。

让Bean了解容器:

运行在Spring中的Bean,就像是《黑客帝国》中的人类,无知便是福。

Spring的Bean不知道自己,也不需要知道自己运行在Spring的容器中。这通常是好事,因为一旦让Bean了解容器,那它就与Spring耦合了。从而可能无法在容器之外生存。

但在某些情况下,Bean需要了解自己在Spring中的名称,了解自己运行的环境。

通过实现BeanNameAware,BeanFactoryAware,ApplicationContextAware接口,可以让Bean了解它的名称、BeanFactory、ApplicationContext。

BeanNameAware

通过实现接口BeanNameAware的方法setBeanName可以获知自己的名称

ApplicationContextAware:

在某些情况下,Bean有时也需要访问程序的上下文。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Johnny_Cheung

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值