Spring.docx
《Spring.docx》由会员分享,可在线阅读,更多相关《Spring.docx(18页珍藏版)》请在冰豆网上搜索。
![Spring.docx](https://file1.bdocx.com/fileroot1/2022-11/26/05e8f704-8994-4aa9-aea7-c27c98dc0f09/05e8f704-8994-4aa9-aea7-c27c98dc0f091.gif)
Spring
控制反转:
应用本身不负责依赖对象的创建以及维护,依赖对象的创建和维护是由外部容器负责的.这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转.
例如:
原来的业务类
UserBizImpl{
UserDaodao=newUserDaoImpl();//严重的依赖
publicbooleanaddUser(Useruser){}
}
可以改为
UserBizImpl{
UserDaodao;
//通过构造器注入对象
publicUserBizImpl(UserDaodao){
this.dao=dao;
}
//通过setter方法注入对象
publicvoidsetDao(UserDaodao){
this.dao=dao;
}
publicbooleanaddUser(Useruser){}
}
所谓的依赖注入就是:
在运行期间,由外部容器动态的将以来的对象注入到组件中.
使用Spring带来的好处:
1.降低组件之间的耦合度,实现软件各层之间的解耦
2.可以使用容器提供的众多服务,如:
事务管理服务,持久化服务等等;当我们使用容器管理事务时,开发人员不需要手动控制事务,也不需要复杂的事务传播
例如:
关于事务管理
Hibernate代码:
publicvoidsave(){
Sessionsession=HibernateSessionFactory.getSession();
session.begintransaction();
//持久化操作代码
session.save(...);
session.getTransaction().commit();
//catch{
session.getTransaction().rollback();
}
}
Jdbc事务管理代码:
Connectionconn=null;
try{
...
conn.setAutoCommit(false);
Statementstmt=conn.createStatement();
stmt.executeUpdate("update....");
mit();
}catch(Exceptione){
conn.rollback();
}finally{
conn.close();
}
3.容器提供单利模式支持,开发人员不需要再自己编写实现代码
4.容器提供了AOP技术,利用它很容易实现权限拦截,运行期监控等功能.
5.容器提供了众多的辅助类,使用这些类能够加快应用的开发,例如JdbcTemplate,HibernateTemplate.
6.Spring对于主流的应用框架提供了集成支持,例如集成Hibernate,Struts等,更便于应用的开发.
?
Spring是轻量级框架还是重量级框架.
答:
轻量级还是重量级主要看它使用了多少服务.对于Spring容器,它提供了很多服务,但是这些服务并不是默认为应用打开的.
如果只使用spring核心服务,我们可以认为此时应用输入轻量级的,如果使用了spring提供的大量的服务,则可以认为此时输入重量级.例如EJB,EJB容器就因为它默认为应用提供了EJB规范中的所有功能,所以它属于重量级.
搭建Spring开发环境
●把以下jar包加入到工程的classpath下:
•dist\spring.jar:
该文件中包含了所有标准的spring模块
•lib\jakarta-commons\commons-logging.jar:
spring使用该库输出日志信息
●如果使用了AOP,还需要下列jar文件
•Lib/aspect/aspectjweaver.jar和aspectjrt.jar
•Lib/cglib/cglib-nodep-2.X.X.jar
●如果使用JSR-250中的注解,入@Resource/@PostConstruct/@PreDestroy,还需要下列jar文件
•Lib/j2ee/common-annotations.jar
●Spring的配置文件:
一个典型的Spring项目需要创建一个或多个Bean配置文件,这些配置文件用于在SpringIOC容器里配置Bean.Bean的配置文件可以放在classpath下,也可以放在其它目录下.
xmlversion="1.0"encoding="UTF-8"?
>
//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-2.5.xsd">
--theapplicationcontextdefinitionforthespringappDispatcherServlet-->
•可以复制samples\jpetstore\war\WEB-INF\applicationContext.xml
实例化Spring容器的两种方式:
1.在类路径下寻找配置文件来实例化容器
ApplicationContextctx=newClassPathXmlApplicationContext(newString[]{“bean.xml”});
2.在文件系统路径下寻找配置文件来实例化容器
ApplicationContextctx=newFileSystemXmlApplicationContext(newString[]{“d:
\\bean.xml”});
注:
Spring的配置文件可以有多个,可以通过String数组传入.
注:
如果只有一个配置文件可以直接写”bean.xml”配置文件路径
//ctx.close()释放容器
补充:
spring编写配置文件时的提示信息
简单示例
1.将一个bean教给spring容器管理.输出一句helloworld
三种实例化bean的方式
1.使用类构造器实例化
//调用默认的构造函数获取对象
2.使用静态工厂方法实例化
class=”com.accp.UserServiceFactory”factory-method=”createUserService”/>
publicclassUserServiceFactory{
publicstaticUserServicecreateUserService(){
returnnewUserServiceImpl();
}
}
3.使用实例工厂方法实例化
factory-bean=”userServiceFactory”factory-method=”createUserService”/>
publicclassUserServiceFactory{
publicUserServicecreateUserService{
returnnewUserServiceImpl();
}
}
Bean的作用域:
可以在测试类中拿两次然后对比一下.
singleton<单态>:
是所有Bean的默认作用域.(购物车的实现显然不能使用singleton)在每个SpringIoC容器中一个bean定义只有一个对象实例.默认情况下会在容器启动时初始化bean,但我们可以指定bean节点的lazy-init=”true”来延迟初始化bean,这时候只有第一次获取bean才会初始化bean.如:
如果想对所有的bean都应用延迟初始化,可以在根节点beans设置default-lazy-init=”true”,如下:
Prototype<标准>每次调用都会创建单独的对象.
其它:
session,request,globalSession作用域为webApplicationContext环境适用.
注:
在低版本的Spring中,由于只有两个Bean作用域(singleton和prototype),所以采自用singlon=”true|false”的配置方式,Spring2.0为了向后兼容,依旧支持这种配置方式。
不过,spring2.0推荐采自新的配置方式:
scope=”<作用域类型>”
(补充:
定制Bean的初始化和销毁过程)
情景:
在企业开发中,组件在使用之前往往需要执行一些特定类型的初始化任务,其中包括打开文件,打开网络/数据库连接,分配内存等.同样,当组件结束其生命周期时,也需要执行与之对应的销毁任务.
●SpringIOC容器可以管理Bean的生命周期,Spring允许在Bean生命周期的特定点执行定制的任务.
●SpringIOC容器对Bean的生命周期进行管理的过程:
•通过构造器或工厂方法创建Bean实例
•为Bean的属性设置值和对其他Bean的引用
•调用Bean的初始化方法
•Bean可以使用了
•当容器关闭时,调用Bean的销毁方法
示例:
在购物结账时,购物员的每次交易都要打开账本,然后是记账,最后要关闭账本.
使用注解的方法(@Spring2.5)
●在Bean的声明里设置init-method和destroy-method属性,为Bean指定初始化和销毁方法.
●Spring2.5里也可以给初始化和销毁方法添加生命周期注解@PostConstructor和@PreDestory
•为了让Spring调用初始化和销毁方法,需要在IOC容器里注册CommonAnnotationBeanPostProcessor实例:
•在配置文件中首先增加context命名空间,然后在配置文件中添加annotation-config/>元素,此时Spring会自动注册CommonAnnotationBeanPostProcessor实例
IOC和DI
IOC(InversionofControl):
其思想是反转资源获取的方向.传统的资源查找方式要求组件向容器发起请求查找资源.作为回应,容器适时的返回资源.而应用了IOC之后,则是容器主动地将资源推送给它所管理的组件,组件所要做的仅是选择一种合适的方式来接受资源.这种行为也被称为查找的被动形式
DI(DependencyInjection):
IOC是一种通用的设计原则,而DI则是具体的设计模式,它体现了IOC设计原则.在DI模式里,容器以一些预先定义好的方式(例如:
setter方法)将匹配的资源注入到每个组件里.
注入依赖对象
基本类型对象注入:
//构造器注入
//属性setter方法注入,
//注意:
基本类型复制适用value,引用bean适用ref
注入其它bean:
方式一:
方式二(适用内部bean,但该bean不能为其它bean所使用.)
补充
在Bean配置文件中声明Bean
为了让SpringIOC容器能够对Bean进行实例化,每个Bean都应该提供一个唯一的名称和一个全限定类名.
对Bean的每个简单类型的属性来说,可以为其制定元素.Spring会尝试将值转换为该属性的声明类型
setter注入使用元素,使用name属性指定Bean的属性名称
(setter注入的另一种写法:
xxxx
)
构造器注入在元素里声明属性,因为构造器的参数是基于位置的,所以中没有name属性
(
构造器注入的另一种写法:
xxx
)
在Spring的IOC容器里配置Bean
setter注入:
最流行的DI类型.容器通过组件里的setter方法注入依赖.
优点:
setter方法可以自动生成;简单
缺点:
组件使用者或许会忘记给组件注入它需要的依赖;在第一次注入后,依赖可能会因为setter方法的调用而被修改
构造器注入:
通过构造器注入依赖.
优点:
解决了setter注入的缺点
缺点:
需通过参数位置来确定参数;若组件有多个依赖需要注入,会导致构造器参数列表非常冗长.
在Bean的配置文件中,可以通过[元素为Bean的属性或构造器参数指定对Bean的引用.]
通过依赖检查来检查属性
IOC容器里可能会声明很多的Bean,这些Bean之间的依赖关系通常会比较复杂.使用setter注入并不能保证属性一定会被注入.
Spring的依赖检查特性可以检查Bean上的某些类型的所有属性是否被设置.
Spring的依赖检查特性只需在的dependency-check属性里指定依赖检查模式即可*.
Spring的依赖检查特性只能检查属性是否被设置,但对设置的属性值是null的情况则无能为力.
Spring的依赖检查特性只对属性是否通过setter方法设置进行检查.所以,即使通过构造器注入,依然会抛出异常
补充:
适用@Required注解检查属性
●Spring的依赖检查特性只能检查某些类型的所有属性.不能只针对个别属性进行检查.
●RequiredAnnotationBeanPostProcessor是Spring的Bean后置处理器,它检查所有具有@Required注解的属性是否已被设置.
在setter方法前增加@Required注解
●Bean后置处理器是一种特殊类型的SpringBean,它能够在每个Bean实例化后执行一些额外的工作.
●要激活Bean后置处理器来进行属性检查,必须在SpringIOC容器里注册它.
Spring2.0,或2.5
在spring配置文件中:
增加
Spring2.5:
在配置文件中首先增加context命名空间,
为其增加指定的dtd文件:
在配置文件中加入下列配置:
annotation-config/>
注意:
要使用注解,必须在当前应用的classpath下包含
lib\j2ee\common-annotations.jar.若当前应用使用的是JavaSE6则不用导入
●RequiredAnnotationBeanPostProcessor只能检查属性是否被设置,但对设置的属性值是null的情况则无能为力.
集合类型的装配
配置List,Array,Set
配置java.util.List类型的属性,需要指定标签,在标签里包含一些元素.这些标签可以通过指定简单的常量值,通过[指定对其他Bean的引用.通过指定内置Bean定义.通过指定空元素.甚至可以内嵌其他集合.]
数组的定义和List一样,都使用
配置java.util.Set需要使用标签,定义元素的方法与List一样.
privateSetsets=newHashSet();//省略getter…setter…
第一个值
第二个值
…
privateListlists=newArrayList();//省略getter…setter…
第一个值
第二个值
…
配置Map,Properties
Java.util.Map通过
必须在标签里定义键
因为键和值的类型没有限制,所以可以自由地为它们指定,[,或元素.]
可以将Map的键和值作为的属性定义:
简单常量使用key和value来定义;Bean引用通过key-ref和value-ref属性定义
使用定义java.util.Properties,该标签使用多个作为子标签.每个标签必须定义key属性.
privateMapmaps=newHashMap();//省略getter…setter…
…
privatePropertiesproperties=newProperties();//省略getter…setter…
第一个值
第二个值
…
使用utilityscheme定义集合
使用基本的集合标签定义集合时,不能将集合作为独立的Bean定义,导致其他Bean无法引用该集合,所以无法在不同Bean之间共享集合.
可以使用utilschema里的集合标签定义独立的集合Bean.需要注意的是,必须在根元素里添加utilschema定义
继承Bean配置
Spring允许将通用的Bean配置抽象出来,组成一个父Bean.继承这个父Bean的Bean称为子Bean
子Bean从父Bean中继承配置,包括Bean的属性和在元素里的属性.
子Bean也可以覆盖从父Bean继承过来的配置
父Bean可以作为配置模板,也可以作为Bean实例.若只想把父Bean作为模板,可以设置的abstract属性为true,这样Spring将不会实例化这个Bean
并不是元素里的所有属性都会被继承.比如:
autowire,dependency-check,abstract等.
也可以忽略父Bean的class属性,让子Bean指定自己的类,而共享相同的属性配置.但此时abstract必须设为true
XML配置里的Bean自动装配
属性里指定自动装配的模式(开发中较少用)
●SpringIOC容器可以帮助自动装配Bean.需要做的仅仅是在的autowire属性里指定自动装配的模式
●byType(根据类型自动装配):
若