spring总结
⼀、spring的起源和背景
Rod Johson在2002年编著的《Expert one to one J2EE design and development》⼀书中,对Java EE正统框架臃肿、低效、脱离现实的种种现状提出了质疑,并积极寻求探索⾰新之道。以此书为指导思想,他编写了interface21框架,这是⼀个⼒图冲破Java EE传统开发的困境,从实际需求出发,着眼于轻便、灵巧,易于开发、测试和部署的轻量级开发框架。Spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2004年3⽉24⽇,发布了1.0正式版。
Spring致⼒于J2EE应⽤的各层的解决⽅案,⽽不是仅仅专注于某⼀层的⽅案。可以说Spring是企业应⽤开发的“⼀站式”选择,并贯穿表现层、业务层及持久层。然⽽,Spring并不想取代那些已有的框架,⽽与它们⽆缝地整合。
spring的设计⽬标:遵循⼀系列的接⼝标准,这样的好处是只需要简单的Java对象或者Javabean就能进⾏Java EE开发,这样开发的⼊门、测试、应⽤部署都得到了简化。
⼆、spring简介
Spring是⼀个开源的⽤于简化采⽤Java语⾔开发企业级程序的⼀个分层的框架。
Spring是⼀个开源框架,它由Rod Johnson创建。它是为了解决企业应⽤开发的复杂性⽽创建的。Spring使⽤基本的JavaBean来完成以前只可能由EJB完成的事情。然⽽,Spring的⽤途不仅限于服务器端的开发。从简单性、可测试性和松耦合的⾓度⽽⾔,任何Java应⽤都可以从Spring中受益。
三、spring的核⼼模块
Spring 框架是⼀个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核⼼容器之上,核⼼容器定义了创建、配置和管理 bean 的⽅式,组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他⼀个或多个模块联合实现。每个模块的功能如下:
(1)Spring Core:核⼼容器,BeanFactory提供了组件⽣命周期的管理,组件的创建, 装配,销毁等功能
核⼼容器提供 Spring 框架的基本功能。核⼼容器的主要组件是 BeanFactory,它是⼯⼚模式的实现。BeanFactory 使⽤控制反
转(IOC) 模式将应⽤程序的配置和依赖性规范与实际的应⽤程序代码分开。
(2)Spring 上下⽂:
Spring 上下⽂是⼀个配置⽂件,向 Spring 框架提供上下⽂信息。Spring 上下⽂包括企业服务,例如 JNDI、EJB、电⼦邮件、国际化、校验和调度功能。
(3)Spring AOP:提供切⾯⽀持
通过配置管理特性,Spring AOP 模块直接将⾯向⽅⾯的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象⽀持 AOP。Spring AOP 模块为基于 Spring 的应⽤程序中的对象提供了事务管理服务。通过使⽤ Spring AOP,不⽤依赖 EJB 组件,就可以将声明性事务管理集成到应⽤程序中。
(4)Spring DAO:提供事务⽀持,JDBC,DAO⽀持
JDBC DAO 抽象层提供了有意义的异常层次结构,可⽤该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极⼤地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的⾯向 JDBC 的异常遵从通⽤的 DAO 异常层次结构。
(5)Spring ORM:对流⾏的O/R Mapping封装或⽀持
Spring 框架插⼊了若⼲个 ORM 框架,从⽽提供了 ORM 的对象关系⼯具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通⽤事务和 DAO 异常层次结构。
(6)Spring Web 模块:提供Web应⽤上下⽂,对Web开发提供功能上的⽀持,如请求,表单,异常等。
Web 上下⽂模块建⽴在应⽤程序上下⽂模块之上,为基于 Web 的应⽤程序提供了上下⽂。所以,Spring 框架⽀持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的⼯作。
(7)Spring MVC 框架:全功能MVC框架,作⽤等同于Struts。
MVC 框架是⼀个全功能的构建 Web 应⽤程序的 MVC 实现。通过策略接⼝,MVC 框架变成为⾼度可配置的,MVC 容纳了⼤量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。
Spring 框架的功能可以⽤在任何 J2EE 服务器中,⼤多数功能也适⽤于不受管理的环境。Spring 的核⼼要点是:⽀持不绑定到特定 J2EE 服务的可重⽤业务和数据访问对象。毫⽆疑问,这样的对象可以在不同 J2EE 环境 (Web 或 EJB)、独⽴应⽤程序、测试环境之间重⽤。
:
容器最基本的接⼝是BeanFactory,负责配置、创建、管理bean,他的⼦接⼝之⼀:ApplicationContext,也叫做spring的上下⽂。ApplicationContext是BeanFactory的⼦接⼝,在web应
⽤中,通常会⽤到XmlWebApplicationContext、AnnotationCofigWebApplicationContext两个实现类。
(1)ApplicationContext简介
系统创建ApplicationContext容器的时候,默认会预先初始化所有的单例的bean,调⽤构造器创建实例对象,然后通过set⽅法注⼊依赖的对象实例。这样的情况下,也就是说会⾯临着⼀个问题,容器在初始化的时候会有较⼤的性能的消耗,但是⼀旦初始化完成之后,程序在获取单例的bean的时候,⼜会获得较好的性能。
(2)ApplicationContext的事件机制
ApplicationContext的事件机制属于观察者设计模式(设计模式篇会在后期专门推出请读者关注),通过ApplicationEvent和ApplicationListener接⼝,可以实现ApplicationContext的事件处理。
spring事件机制中ApplicationEvent和ApplicationListener起到重要作⽤。其中,ApplicationEvent:由ApplicationContext发布。ApplicationListener可以由容器⾥⾯任何的bean担任。
(3)spring的内置事件:
(1) ContextRefreshedEvent:ApplicationContext容器初始化或者刷新的时候会触发这个事件。
(2) ContextStartedEvent:当使⽤ConfigurableApplicationContext(applicationContext的⼦接⼝)接⼝的start⽅法启动ApplicationContext容器的时候触发这个事件。
(3)ContextClosedEvent:当使⽤ConfigurableApplicationContext(applicationContext的⼦接⼝)接⼝的close⽅法启动ApplicationContext容器的时候触发这个事件。
(4)ContextStoppedEvent:当使⽤ConfigurableApplicationContext(applicationContext的⼦接⼝)接⼝的stop⽅法启动ApplicationContext容器的时候触发这个事件。
(5)RequestHandledEvent:web相关的事件,只能⽤在DispatcherServlet的web应⽤中,在使⽤spring作为mvc控制器的时候,处理完⽤户的请求后,系统会⾃动的调⽤。
另外webSocket服务中,还有,SessionConnectedEvent、SessionConnectEvent、SessionDisconnectEvent三个事件。
四、
1 .依赖和依赖注⼊
传统应⽤程序设计中所说的依赖⼀般指“类之间的关系”
泛化:表⽰类与类之间的继承关系、接⼝与接⼝之间的继承关系;
实现:表⽰类对接⼝的实现;
依赖:当类与类之间有使⽤关系时就属于依赖关系,不同于关联关系,依赖不具有“拥有关系”,⽽是⼀种“相识关系”,只在某个特定地⽅(⽐如某个⽅法体内)才有关系。
关联:表⽰类与类或类与接⼝之间的依赖关系,表现为“拥有关系”;具体到代码可以⽤实例变量来表⽰;
聚合:属于是关联的特殊情况,体现部分-整体关系,是⼀种弱拥有关系;整体和部分可以有不⼀样的⽣命周期;是⼀种弱关联;
组合:属于是关联的特殊情况,也体现了体现部分-整体关系,是⼀种强“拥有关系”;整体与部分有相同的⽣命周期,是⼀种强关联;
IoC容器的依赖有两层含义:Bean依赖容器和容器注⼊Bean的依赖资源:
Bean依赖容器:也就是说Bean要依赖于容器,这⾥的依赖是指容器负责创建Bean并管理Bean的⽣命周期,正是由于由容器来控制创建Bean并注⼊依赖,也就是控制权被反转了,这也正是IoC名字的由来,此处的有依赖是指Bean和容器之间的依赖关系。
容器注⼊Bean的依赖资源:容器负责注⼊Bean的依赖资源,依赖资源可以是Bean、外部⽂件、常量数据等,在中都反映为对象,并且由容器负责组装Bean之间的依赖关系,此处的依赖是指Bean之间的依赖关系,可以认为是传统类与类之间的“关联”、“聚合”、“组合”关系。
为什么要应⽤依赖注⼊,应⽤依赖注⼊能给我们带来哪些好处呢?
动态替换Bean依赖对象,程序更灵活:替换Bean依赖对象,⽆需修改源⽂件:应⽤依赖注⼊后,由于可以采⽤配置⽂件⽅式实现,从⽽能随时动态的替换Bean的依赖对象,⽆需修改java源⽂件;
更好实践⾯向接⼝编程,代码更清晰:在Bean中只需指定依赖对象的接⼝,接⼝定义依赖对象完成的功能,通过容器注⼊依赖实现;
更好实践优先使⽤对象组合,⽽不是类继承:因为IoC容器采⽤注⼊依赖,也就是组合对象,从⽽更好的实践对象组合。
采⽤对象组合,Bean的功能可能由⼏个依赖Bean的功能组合⽽成,其Bean本⾝可能只提供少许功能或根本⽆任何功能,全部委托给依赖Bean,对象组合具有动态性,能更⽅便的替换掉依赖Bean,从⽽改变Bean功能;
⽽如果采⽤类继承,Bean没有依赖Bean,⽽是采⽤继承⽅式添加新功能,,⽽且功能是在编译时就确
定了,不具有动态性,⽽且采⽤类继承导致Bean与⼦Bean之间⾼度耦合,难以复⽤。
增加Bean可复⽤性:依赖于对象组合,Bean更可复⽤且复⽤更简单;
降低Bean之间耦合:由于我们完全采⽤⾯向接⼝编程,在代码中没有直接引⽤Bean依赖实现,全部引⽤接⼝,⽽且不会出现显⽰的创建依赖对象代码,⽽且这些依赖是由容器来注⼊,很容易替换依赖实现类,从⽽降低Bean与依赖之间耦合;
代码结构更清晰:要应⽤依赖注⼊,代码结构要按照规约⽅式进⾏书写,从⽽更好的应⽤⼀些最佳实践,因此代码结构更清晰。
其实依赖注⼊只是⼀种装配对象的⼿段,设计的类结构才是基础,如果设计的类结构不⽀持依赖注⼊,Spring IoC容器也注⼊不了任何东西,从⽽从根本上说“如何设计好类结构才是关键,依赖注⼊只是⼀种装配对象⼿段”。
那容器如何注⼊Bean的依赖资源?
Spring IoC容器注⼊依赖资源主要有以下两种基本实现⽅式:
(1)构造器注⼊:就是容器实例化Bean时注⼊那些依赖,通过在在Bean定义中指定构造器参数进⾏注⼊依赖,包括实例⼯⼚⽅法参数注⼊依赖,但静态⼯⼚⽅法参数不允许注⼊依赖;
(2) setter注⼊:通过setter⽅法进⾏注⼊依赖;
⽅法注⼊:能通过配置⽅式替换掉Bean⽅法,也就是通过配置改变Bean⽅法 功能。
2.依赖注⼊的两种⽅式
2.1构造器注⼊
使⽤构造器注⼊通过配置构造器参数实现,构造器参数就是依赖。除了构造器⽅式,还有静态⼯⼚、实例⼯⼚⽅法可以进⾏构造器注⼊。如图3-1所⽰:
构造器注⼊可以根据参数索引注⼊、参数类型注⼊或Spring3⽀持的参数名注⼊,但参数名注⼊是有限制的,需要使⽤在编译程序时打开调试模式
(1)根据参数索引注⼊,使⽤标签“<constructor-arg index="1" value="1"/>”来指定注⼊的依赖,其中“index”表⽰索引,从0开始,即第⼀个参数索引为0,“value”来指定注⼊的常量值,配置⽅式如下:
(2)根据参数类型进⾏注⼊,使⽤标签“<constructor-arg type="java.lang.String" value="Hello World!"/>”来指定注⼊的依赖,其中“type”表⽰需要匹配的参数类型,可以是基本类型也可以是其他类型,如“int”、“java.lang.String”,“value”来指定注⼊的常量值,配置⽅式如下:
(3)根据参数名进⾏注⼊,使⽤标签“<constructor-arg name="message" value="Hello World!"/>”来指定注⼊的依赖,其
中“name”表⽰需要匹配的参数名字,“value”来指定注⼊的常量值,配置⽅式如下:
2.2setter注⼊
setter注⼊,是通过在通过构造器、静态⼯⼚或实例⼯⼚实例好Bean后,通过调⽤Bean类的setter⽅法进⾏注⼊依赖,如图3-3所⽰:
setter注⼊⽅式只有⼀种根据setter名字进⾏注⼊:
(1) 注⼊简单属性(String和8中基本类型)
<beans>
<bean id=”BeanId” class=”classpath” autowire=” ” dependency-check=” ”>
<property name=”parameterName”>
<value>parameterValue</value>
</property>
</bean>
</beans>
对于基本类型,Spring容器会⾃动作类型转换,以便赋值。
(2) 注⼊对象
<bean>
<ref local=”BeanId”>
</bean>
A、让Spring容器在当前配置⽂件中到相应的Bean,并调⽤set⽅法,注⼊该Bean。
B、将⼀个Bean的定义嵌套在另⼀个Bean中(可读性差),被嵌套的Bean不能采⽤getBean()返回
C、采⽤<ref bean=” ”>搜索多个配置⽂件来注⼊
(3) 注⼊集合类型
① Set
Set中存放字符串,对象,集合,不允许重复
② List
List中可以放⼊字符串,对象,List
③ Map
Map 有<entry>⼦元素来存取key,value,key只能为String
④ Properties
Properties有<props>⼦元素
3.引⽤其它Bean
注⼊依赖Bean及注⼊内部Bean。
构造器注⼊⽅式:
(1)通过” <constructor-arg>”标签的ref属性来引⽤其他Bean,这是最简化的配置:
(2)通过” <constructor-arg>”标签的⼦<ref>标签来引⽤其他Bean,使⽤bean属性来指定引⽤的Bean:
setter注⼊⽅式:
(1)通过” <property>”标签的ref属性来引⽤其他Bean,这是最简化的配置:
(2)通过” <property>”标签的⼦<ref>标签来引⽤其他Bean,使⽤bean属性来指定引⽤的Bean:
设值注⼊和构造注⼊的对⽐
这两种⽅式,效果是⼀样的,注⼊的时机不同,设值注⼊是先调⽤⽆参的构造函数,创建出实例后然后调⽤set⽅法注⼊属性值。⽽构造输⼊是通过在调⽤构造函数初始化实例的同时完成了注⼊。
设值注⼊的优点
1. 通过set的⽅式设定依赖关系显得更加直观,⾃然,和javabean写法类似。
2. 复杂的依赖关系,采⽤构造注⼊会造成构造器过于臃肿,spring 实例化的时候同时实例化其依赖的全部实例,导致性能下降,set⽅式可以避免这些问题。
3. 在成员变量可选的情况下,构造注⼊不够灵活。
构造注⼊的优点
某些特定的情况下,构造注⼊⽐设值注⼊好⼀些。spring系列框架有哪些
1. 构造注⼊可以在构造器中决定依赖关系的注⼊顺序,优先依赖的优先注⼊,构造注⼊可以清楚的分清注⼊的顺序。
2. 组件的调⽤者⽆需知道组件内部的依赖关系,符合⾼内聚原则。
4. Bean的作⽤域
什么是作⽤域呢?即“scope”,在⾯向对象程序设计中⼀般指对象或变量之间的可见范围。⽽在Spring容器中是指其创建的Bean对象相对于其他Bean对象的请求可见范围。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论