ONE:Spring是什么及Spring的优点
①. Spring是一个轻量级的IOC和AOP容器框架
②. Spring是非侵入式的,基于Spring开发的应用一般不依赖于Spring的类
③. Spring是个容器,因为它包含并且管理应用对象的生命周期和配置,比如对象的创建、销毁、回调等
④. Spring提供对事务的管理
⑤. Spring对主流的框架提供了很好的集成支持,比如和hibernate SpringMVC等框架的集成
TWO:对AOP和IOC的理解
IOC:Invert of control,控制反转,也称为DI(依赖注入)。依赖对象的创建和维护交给了spring容器来管理,应用程序本身不需要负责依赖对象的创建和维护,简单理解就是把原本应该我们去new对象这个操作转到spring容器中执行
AOP:面向切面编程,本质就是拦截器,比如项目中的事务和日志就是很好的体现了AOP。比如:操作数据库的增删改之前,都需要开启事务,增删改之后,都需要提交事务,这样我们就可以写一个拦截器,底层就是采用动态代理实现前置通知和后置通知,在前置通知中开启事务,在后置通知中提交事务,在spring.xml中配置通知即可,spring的事务管理底层就用到了AOP
THREE:Spring的注入方式
①. setter注入:对于习惯了传统的JavaBean开发的程序员来说,通过setter方法注入属性值是熟悉的、直观的和自然的。如果依赖关系比较复杂,那么构造方法注入方式会导致构造方法相当庞大,此时使用设值方式更为简洁
②. 构造注入:构造方法注入很好的响应了Java设计原则之一,在构造期间即可创建一个完整、合法的对象;避免了繁琐的setter方法的编写,所有的依赖关系均在构造方法中设定,依赖关系集中体现;
③. 接口注入:接口注入因具备侵入性,它要求组件必须与特定的接口相关联,因此这种注入方式基本上已经被遗弃了。
---------------------分割线-分割线------------不同观点--------------------------------
三种注入方式比较:
接口注入:
接口注入模式因为具备侵入性,它要求组件必须与特定的接口相关联,因此并不被看好,实际使用有限。
Setter 注入:更广泛
对于习惯了传统 javabean 开发的程序员,通过 setter 方法设定依赖关系更加直观。
如果依赖关系较为复杂,那么构造子注入模式的构造函数也会相当庞大,而此时设值注入模式则更为简洁。
如果用到了第三方类库,可能要求我们的组件提供一个默认的构造函数,此时构造子注入模式也不适用。
构造器注入:
在构造期间完成一个完整的、合法的对象。
所有依赖关系在构造函数中集中呈现。
依赖关系在构造时由容器一次性设定,组件被创建之后一直处于相对“不变”的稳定状态。
只有组件的创建者关心其内部依赖关系,对调用者而言,该依赖关系处于“黑盒”之中。
总结
Spring使用注入方式,为什么使用注入方式,这系列问题实际归结起来就是一句话,Spring的注入和IoC(本人关于IoC的阐述)反转控制是一回事。
理论上:第三种注入方式(构造函数注入)在符合java使用原则上更加合理。
实际上:我个人认为第二种注入方式(setter注入)可以取得更加直观的效果,在使用工作上有不可比拟的优势,所以setter注入依赖关系应用更加广泛。
FOUR:如何定义bean的作用域,作用域之间的区别
定义bean的作用域,在<bean>中与一个scope的属性,取值有5中
①. singleton:单例模式(默认),也就是说这种范围不管接收到多少个请求,每个容器中之后一个bean的实例。
②. prototype:原型模式,和单例模式相反,为每一个bean请求提供一个实例。
③. request:针对每一次HTTP请求都会产生一个新的bean,并且该bean仅在当前request内有效,请求完成以后,bean会失效并被垃圾回收器回收
④. session:针对每一次HTTP请求都会产生一个新的bean,并且该bean仅在当前session内有效,session过期后,bean也会随之失效
⑤. Global session:global session和portlet应用相关,当你的应用部署在Portlet容器中工作时,如果你想让所有的portlet共用全局存储变量的话,就需要存储到global session中
======================================================================================
作用域包括:
singleton
全局只有一个实例
prototype
每次调用产生一个新的实例
在web使用的时候还有三个作用域,但是必须在web.xml中注册一个RequestContextListener , 目的是为了设置每次请求开始和结束都可以使spring得到相应的事件。
request
每次请求产生一个bean
session
每个用户session可以产生一个新的bean,不同用户之间的bean互相不影响
globalSession
作用和session类似,只是使用portlet的时候使用。
FIVE:什么是spring的自动装配?并解释一下自动装配的各种模式
Spring的自动装配:无须在Spring配置文件中描述javabean之间的依赖关系,IOC容器会自动建立JavaBean之间的关联关系。
①. 根据属性名称自动装配autowire=”byName”
②. 根据数据类型自动装配autowire=”byType”
③. 根据构造方法自动装配autowire=”constructor”
SIX:能否在spring中注入null或者空字符串
可以
注入null值
<property name=”email”><null/></property>
注入空字符串:
<property name=”email” value=””></property>
SEVEN:配置Spring数据库驱动
①. 可以使用c3p0数据库连接池技术
②. 使用DriverManagerDataSource数据源来配置数据库驱动
EIGHT:介绍一下spring的事务管理
首先要搞明白为什么需要事务?
举个例子:比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱;然后ATM出1000元钱。这两个步骤必须是要么都执行要么都不执行。如果银行卡扣除了1000块但是ATM出钱失败的话,你将会损失1000元;如果银行卡扣钱失败但是ATM却出了1000块,那么银行将损失1000元。所以,如果一个步骤成功另一个步骤失败对双方都不是好事,如果不管哪一个步骤失败了以后,整个取钱过程都能回滚,也就是完全取消所有操作的话,这对双方都是极好的。事务就是用来解决类似问题的。
补充====================================================================
Spring并不直接管理事务,而是提供了多种事务管理器,他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。
Spring事务管理器的接口是org.springframework.transaction.PlatformTransactionManager,通过这个接口,Spring为各个平台如JDBC、Hibernate等都提供了对应的事务管理器,但是具体的实现就是各个平台自己的事情了。
Public interface PlatformTransactionManager()...{
// 由TransactionDefinition得到TransactionStatus对象
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
// 提交
Void commit(TransactionStatus status) throws TransactionException;
// 回滚
Void rollback(TransactionStatus status) throws TransactionException;
事务最重要的两个特性是事务的传播级别和数据隔离级别
传播级别:定义的是事务的控制范围,常用的就是PROPAGATION_REQUIRED
数据隔离级别:定义的是事务在数据库读写方面的控制范围
事务的配置有两种方式:注解式事务和声明式事务