Spring手册-职业技能培训课件_第1页
Spring手册-职业技能培训课件_第2页
Spring手册-职业技能培训课件_第3页
Spring手册-职业技能培训课件_第4页
Spring手册-职业技能培训课件_第5页
已阅读5页,还剩91页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Spring手册上海浦东软件园·职业技能培训Spring手册上海浦东软件园·职业技能培训

Spring是什么Spring是一个开源的控制反转(InversionofControl,IoC)和面向切面(AOP)的容器框架.它的主要目得是简化企业开发.

Spring是什么Spring是一个开源的控制反转(In

IOC控制反转publicclassPersonServiceBean{

privatePersonDaopersonDao=new

PersonDaoBean();

publicvoidsave(Personperson){personDao.save(person);}}PersonDaoBean是在应用内部创建及维护的。所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转。

IOC控制反转publicclassPerson

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

privatePersonDaopersonDao;

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

publicPersonServiceBean(PersonDaopersonDao){this.personDao=personDao;}

publicvoidsave(Personperson){personDao.save(person);}}所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中。

依赖注入(DependencyInjection)当我

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

可以使用容器提供的众多服务,如:事务管理服务、消息服务等等。当我们使用容器管理事务时,开发人员就不再需要手工控制事务.也不需处理复杂的事务传播。容器提供单例模式支持,开发人员不再需要自己编写实现代码。容器提供了AOP技术,利用它很容易实现如权限拦截、运行期监控等功能。容器提供的众多辅作类,使用这些类能够加快应用的开发,如:JdbcTemplate、HibernateTemplate。Spring对于主流的应用框架提供了集成支持,如:集成Hibernate、JPA、Struts等,这样更便于应用的开发。ControllerServiceDAO

为何要使用Spring至少在我看来,在项目中引入spri

使用Spring的好处当使用spring时,我们可以使用容器提供的众多服务

使用Spring的好处

如果使用Spring,我们就不再需要手工控制事务Hibernate的事务操作:publicvoidsave(){ Sessionsession=sessionFactory.getCurrentSession();

session.beginTransaction(); Infoinfo=newInfo("传智播客");info.setContent("国内实力最强的java培训机构");session.save(info);

session.getTransaction().commit();}JDBC的事务操作:

Connectionconn=null;try{.......

conn.setAutoCommit(false);Statementstmt=conn.createStatement();stmt.executeUpdate("updatepersonwherename='叶天'");

mit();.....

}catch(Exceptione){

conn.rollback();}finally{conn.close();}

如果使用Spring,我们就不再需要手工控制事务Hib

另外,如果使用spring,我们也不需要处理复杂的事务传播行为publicvoidpayment(){Bean1.update();//更新金额Bean2.save();//记录操作日志}如果我们不使用Spring,针对下面这两种业务需求,我们该如何做?第1种可能的业务需求:要求Bean1.update()和Bean2.save()在同一个事务中执行。第2种可能的业务需求:要求不管Bean1.update()的事务是否成功,都需要记录操作日志。publicclassBean1{

publicvoidupdate(){//注意:下面省略了一些代码 Connectionconn=null; conn.setAutoCommit(false);

Statement.executeUpdate(“updateaccountsetamount=?whereid=?");

}}publicclassBean2{

publicvoidsave(){//注意:下面省略了一些代码 Connectionconn=null; conn.setAutoCommit(false);

Statement.executeUpdate(“insertintoLog(content)values(?)");

}}

另外,如果使用spring,我们也不需要处理复杂的事务

使用Spring,不再需要我们处理复杂的事务传播行为使用Spring,我们只需要通过声明式的事务属性配置就可以轻松地实现这两种业务需求1.要求Bean1.update()和Bean2.save()的在同一个事务中执行2.要求不管Bean1.update()的事务是否成功,都需要记录日志。@Transactional(propagation=Propagation.Required)publicvoidpayment(){Bean1.update();//更新金额Bean2.save();//记录日志}

publicclassBean1{@Transactional(propagation=Propagation.Required)

publicvoidupdate(){

executeUpdate(“updateaccountsetamount=?whereid=?");

}}publicclassBean2{

@Transactional(propagation=Propagation.RequiresNew)

publicvoidsave(){ executeUpdate(“insertintoLog(content)values(?)");}}

使用Spring,不再需要我们处理复杂的事务传播行为使用

轻量级与重量级概念的划分经常会有同学问到spring属于轻量级框架,还是重量框架?其实划分一个应用是否属于轻量级还是重量级,主要看它使用了多少服务.使用的服务越多,容器要为普通java对象做的工作就越多,必然会影响到应用的发布时间或者是运行性能.对于spring容器,它提供了很多服务,但这些服务并不是默认为应用打开的,应用需要某种服务,还需要指明使用该服务,如果应用使用的服务很少,如:只使用了spring核心服务,那么我们可以认为此时应用属于轻量级的,如果应用使用了spring提供的大部分服务,这时应用就属于重量级。目前EJB容器就因为它默认为应用提供了EJB规范中所有的功能,所以它属于重量级。

轻量级与重量级概念的划分经常会有同学问到spring属于

使用Spring需要的jar

使用Spring需要的jar

spring的配置文件模版

spring的配置文件模版

编写spring配置文件时,不能出现帮助信息

编写spring配置文件时,不能出现帮助信息

实例化spring容器实例化Spring容器常用的两种方式:方法一:在类路径下寻找配置文件来实例化容器ApplicationContextctx=newClassPathXmlApplicationContext(newString[]{"beans.xml"});方法二:在文件系统路径下寻找配置文件来实例化容器ApplicationContextctx=newFileSystemXmlApplicationContext(newString[]{“d:\\beans.xml“});Spring的配置文件可以指定多个,可以通过String数组传入。

实例化spring容器实例化Spring容器常用的两种方

从spring容器中得到bean当spring容器启动后,因为spring容器可以管理bean对象的创建,销毁等生命周期,所以我们只需从容器直接获取Bean对象就行,而不用编写一句代码来创建bean对象。从容器获取bean对象的代码如下:ApplicationContextctx=newClassPathXmlApplicationContext(“beans.xml”);OrderServiceservice=(OrderService)ctx.getBean("personService");

从spring容器中得到bean当spring容器启动后

使用dom4j读取spring配置文件

使用dom4j读取spring配置文件

三种实例化bean的方式1.使用类构造器实例化<beanid=“orderService"class="cn.itcast.OrderServiceBean"/>2.使用静态工厂方法实例化<beanid="personService"class="cn.itcast.service.OrderFactory"factory-method="createOrder"/>publicclassOrderFactory{ publicstaticOrderServiceBeancreateOrder(){ returnnewOrderServiceBean(); }}3.使用实例工厂方法实例化:<beanid="personServiceFactory"class="cn.itcast.service.OrderFactory"/><beanid="personService"factory-bean="personServiceFactory"factory-method="createOrder"/>publicclassOrderFactory{ publicOrderServiceBeancreateOrder(){ returnnewOrderServiceBean(); }}

三种实例化bean的方式1.使用类构造器实例化

Bean的作用域.singleton

在每个SpringIoC容器中一个bean定义只有一个对象实例。默认情况下会在容器启动时初始化bean,但我们可以指定Bean节点的lazy-init=“true”来延迟初始化bean,这时候,只有第一次获取bean会才初始化bean。如:

<beanid="xxx"class="cn.itcast.OrderServiceBean"lazy-init="true"/>如果想对所有bean都应用延迟初始化,可以在根节点beans设置default-lazy-init=“true“,如下:<beansdefault-lazy-init="true“...>.prototype

每次从容器获取bean都是新的对象。

.request.session.globalsession

Bean的作用域.singleton

指定Bean的初始化方法和销毁方法指定Bean的初始化方法和销毁方法<beanid="xxx"class="cn.itcast.OrderServiceBean"init-method="init"destroy-method="close"/>

指定Bean的初始化方法和销毁方法指定Bean的初始化注入依赖对象基本类型对象注入:<beanid="orderService"class="cn.itcast.service.OrderServiceBean"> <constructor-argindex=“0”type=“java.lang.String”value=“xxx”/>//构造器注入 <propertyname=“name”value=“zhao/>//属性setter方法注入</bean>注入其他bean:方式一<beanid="orderDao"class="cn.itcast.service.OrderDaoBean"/><beanid="orderService"class="cn.itcast.service.OrderServiceBean"> <propertyname="orderDao"ref="orderDao"/></bean>方式二(使用内部bean,但该bean不能被其他bean使用)<beanid="orderService"class="cn.itcast.service.OrderServiceBean"> <propertyname="orderDao"> <beanclass="cn.itcast.service.OrderDaoBean"/> </property></bean>注入依赖对象基本类型对象注入:集合类型的装配publicclassOrderServiceBean{ privateSet<String>sets=newHashSet<String>(); privateList<String>lists=newArrayList<String>(); privatePropertiesproperties=newProperties(); privateMap<String,String>maps=newHashMap<String,String>();....//这里省略属性的getter和setter方法}集合类型的装配publicclassOrderServi集合类型的装配<beanid="order"class="cn.itcast.service.OrderServiceBean"><propertyname="lists"><list> <value>lihuoming</value></list></property> <propertyname="sets"><set><value>set</value></set></property> <propertyname="maps"><map><entrykey="lihuoming"value="28"/></map></property> <propertyname="properties"><props> <propkey="12">sss</prop></props></property></bean>集合类型的装配<beanid="order"class=依赖注入使用构造器注入使用属性setter方法注入使用Field注入(用于注解方式)注入依赖对象可以采用手工装配或自动装配,在实际应用中建议使用手工装配,因为自动装配会产生未知情况,开发人员无法预见最终的装配结果。1.手工装配依赖对象2.自动装配依赖对象依赖注入使用构造器注入依赖注入--手工装配依赖注入--手工装配依赖注入--手工装配在java代码中使用@Autowired或@Resource注解方式进行装配,这两个注解的区别是:@Autowired默认按类型装配,@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。@AutowiredprivatePersonDaopersonDao;//用于字段上@AutowiredpublicvoidsetOrderDao(OrderDaoorderDao){//用于属性的setter方法上this.orderDao=orderDao;}@Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false。如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。如下:@Autowired@Qualifier("personDaoBean")privatePersonDaopersonDao;@Resource注解和@Autowired一样,也可以标注在字段或属性的setter方法上,但它默认按名称装配。名称可以通过@Resource的name属性指定,如果没有指定name属性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。

@Resource(name=“personDaoBean”)privatePersonDaopersonDao;//用于字段上注意:如果没有指定name属性,并且按照默认的名称仍然找不到依赖对象时,@Resource注解会回退到按类型装配。但一旦指定了name属性,就只能按名称装配了。依赖注入--手工装配在java代码中使用@Autowired依赖注入--自动装配依赖对象对于自动装配,大家了解一下就可以了,实在不推荐大家使用。例子:<beanid="..."class="..."autowire="byType"/>autowire属性取值如下:byType:按类型装配,可以根据属性的类型,在容器中寻找跟该类型匹配的bean。如果发现多个,那么将会抛出异常。如果没有找到,即属性值为null。byName:按名称装配,可以根据属性的名称,在容器中寻找跟该属性名相同的bean,如果没有找到,即属性值为null。constructor与byType的方式类似,不同之处在于它应用于构造器参数。如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。autodetect:通过bean类的自省机制(introspection)来决定是使用constructor还是byType方式进行自动装配。如果发现默认的构造器,那么将使用byType方式。依赖注入--自动装配依赖对象对于自动装配,大家了解一下就可以通过在classpath自动扫描方式把组件纳入spring容器中管理通过在classpath自动扫描方式把组件纳入spring容

JDK动态代理publicclassJDKProxyimplements

InvocationHandler{

private

ObjecttargetObject;//代理的目标对象

public

ObjectcreateProxyInstance(ObjecttargetObject){

this.targetObject=targetObject;/**第一个参数设置代码使用的类装载器,一般采用跟目标类相同的类装载器*第二个参数设置代理类实现的接口*第三个参数设置回调对象,当代理对象的方法被调用时,会委派给该参数指定对象的invoke方法*/

return

Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(),

this.targetObject.getClass().getInterfaces(),this); }

public

Objectinvoke(Objectproxy,Methodmethod,Object[]args) throwsThrowable{

returnmethod.invoke(this.targetObject,args);//把方法调用委派给目标对象

}}当目标类实现了接口,我们可以使用jdk的Proxy来生成代理对象。

JDK动态代理publicclassJDKProx

使用CGLIB生成代理publicclassCGLIBProxyimplements

MethodInterceptor{

private

ObjecttargetObject;//代理的目标对象

public

ObjectcreateProxyInstance(ObjecttargetObject){

this.targetObject=targetObject; Enhancerenhancer=newEnhancer();//该类用于生成代理对象

enhancer.setSuperclass(this.targetObject.getClass());//设置父类

enhancer.setCallback(this);//设置回调用对象为本身

returnenhancer.create(); }

public

Objectintercept(Objectproxy,Methodmethod,Object[]args,

MethodProxymethodProxy)throwsThrowable{

returnmethodProxy.invoke(this.targetObject,args); }}CGLIB可以生成目标类的子类,并重写父类非final修饰符的方法。

使用CGLIB生成代理publicclassCGLI

AOP中的概念Aspect(切面):指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样,类是对物体特征的抽象,而切面横切性关注点的抽象.joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点,实际上joinpoint还可以是field或类构造器)Pointcut(切入点):所谓切入点是指我们要对那些joinpoint进行拦截的定义.Advice(通知):所谓通知是指拦截到joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知Target(目标对象):代理的目标对象Weave(织入):指将aspects应用到target对象并导致proxy对象创建的过程称为织入.Introduction(引入):在不修改类代码的前提下,Introduction可以在运行期为类动态地添加一些方法或Field.

AOP中的概念Aspect(切面):指横切性关注点的抽象

使用Spring进行面向切面(AOP)编程

使用Spring进行面向切面(AOP)编程

基于注解方式声明切面

基于注解方式声明切面

基于注解方式声明切面@AspectpublicclassLogPrint{

@Pointcut("execution(*cn.itcast.service..*.*(..))") privatevoidanyMethod(){}//声明一个切入点

@Before("anyMethod()&&args(userName)")//定义前置通知

publicvoiddoAccessCheck(StringuserName){ }

@AfterReturning(pointcut="anyMethod()",returning="revalue")//定义后置通知

publicvoiddoReturnCheck(Stringrevalue){ }

@AfterThrowing(pointcut="anyMethod()",throwing="ex")//定义例外通知

publicvoiddoExceptionAction(Exceptionex){ }

@After("anyMethod()")//定义最终通知

publicvoiddoReleaseAction(){ }

@Around("anyMethod()")//环绕通知

publicObjectdoBasicProfiling(ProceedingJoinPointpjp)throwsThrowable{ returnceed(); }}

基于注解方式声明切面@Aspect

基于基于XML配置方式声明切面publicclassLogPrint{ publicvoiddoAccessCheck(){}定义前置通知 publicvoiddoReturnCheck(){}定义后置通知publicvoiddoExceptionAction(){}定义例外通知 publicvoiddoReleaseAction(){}定义最终通知 publicObjectdoBasicProfiling(ProceedingJoinPointpjp)throwsThrowable{ returnceed();环绕通知 }}

基于基于XML配置方式声明切面publicclass

基于基于XML配置方式声明切面<beanid="orderservice"class="cn.itcast.service.OrderServiceBean"/><beanid="log"class="cn.itcast.service.LogPrint"/><aop:config><aop:aspectid="myaop"ref="log"> <aop:pointcutid="mycut"expression="execution(*cn.itcast.service..*.*(..))"/> <aop:beforepointcut-ref="mycut"method="doAccessCheck"/> <aop:after-returningpointcut-ref="mycut"method="doReturnCheck"/> <aop:after-throwingpointcut-ref="mycut"method="doExceptionAction"/> <aop:afterpointcut-ref="mycut"method=“doReleaseAction"/> <aop:aroundpointcut-ref="mycut"method="doBasicProfiling"/></aop:aspect></aop:config>

基于基于XML配置方式声明切面<beanid="ord

Spring+JDBC组合开发

使用Spring+JDBC集成步骤如下:配置数据源,如:<beanid="dataSource"class="mons.dbcp.BasicDataSource"destroy-method="close"><propertyname="driverClassName"value="org.gjt.mm.mysql.Driver"/><propertyname="url"value="jdbc:mysql://localhost:3306/itcast?useUnicode=true&characterEncoding=UTF-8"/><propertyname="username"value="root"/><propertyname="password"value="123456"/>.....略</bean>配置事务。配置事务时,需要在xml配置文件中引入用于声明事务的tx命名空间(见下页),事务的配置方式有两种:注解方式和基于XML配置方式。

Spring+JDBC组合开发使用Spring+JDB

在spring配置文件中引入用于声明事务的tx命名空间

在spring配置文件中引入用于声明事务的tx命名空间

配置数据源<beanid="dataSource"class="mons.dbcp.BasicDataSource"destroy-method="close"><propertyname="driverClassName"value="org.gjt.mm.mysql.Driver"/><propertyname="url"value="jdbc:mysql://localhost:3306/itcast?useUnicode=true&characterEncoding=UTF-8"/><propertyname="username"value="root"/><propertyname="password"value="123456"/><!--连接池启动时的初始值--> <propertyname="initialSize"value="1"/> <!--连接池的最大值--> <propertyname="maxActive"value="500"/> <!--最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止--> <propertyname="maxIdle"value="2"/> <!--最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请--> <propertyname="minIdle"value="1"/></bean>使用<context:property-placeholderlocation=“perties”/>属性占位符

配置数据源<beanid="dataSource"

使用属性占位符方式配置数据源<context:property-placeholderlocation=“perties”/>

<beanid="dataSource"class="mons.dbcp.BasicDataSource"destroy-method="close"><propertyname="driverClassName"value="${driverClassName}"/><propertyname="url"value="${url}"/><propertyname="username"value="${username}"/><propertyname="password"value="${password}"/><!--连接池启动时的初始值--> <propertyname="initialSize"value="${initialSize}"/> <!--连接池的最大值--> <propertyname="maxActive"value="${maxActive}"/> <!--最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止--> <propertyname="maxIdle"value="${maxIdle}"/> <!--最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请--> <propertyname="minIdle"value="${minIdle}"/></bean>

使用属性占位符方式配置数据源<context:prope

采用注解方式配置事务采用注解方式<beanid="txManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <propertyname="dataSource"ref="dataSource"/></bean><!–采用@Transactional注解方式使用事务-->

<tx:annotation-driventransaction-manager="txManager"/>@Service@TransactionalpublicclassPersonServiceBeanimplementsPersonService{}

采用注解方式配置事务采用注解方式

采用基于XML方式配置事务<beanid="txManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <propertyname="dataSource"ref="dataSource"/></bean><aop:config> <aop:pointcutid="transactionPointcut"expression="execution(*cn.itcast.service..*.*(..))"/> <aop:advisoradvice-ref="txAdvice"pointcut-ref="transactionPointcut"/></aop:config><tx:adviceid="txAdvice"transaction-manager="txManager"> <tx:attributes> <tx:methodname="get*"read-only="true"propagation="NOT_SUPPORTED"/> <tx:methodname="*"/> </tx:attributes></tx:advice>

采用基于XML方式配置事务<beanid="txMan

使用JdbcTemplate进行insert/update/delete操作@Service@TransactionalpublicclassPersonServiceBeanimplementsPersonService{

privateJdbcTemplatejdbcTemplate;

@Resource publicvoidsetDataSource(DataSourcedataSource){ this.jdbcTemplate=newJdbcTemplate(dataSource); }//添加 publicvoidsave(Personperson)throwsException{ jdbcTemplate.update("insertintoperson(name)values(?)", newObject[]{person.getName()},newint[]{java.sql.Types.VARCHAR}); }}

使用JdbcTemplate进行insert/updat

使用JdbcTemplate获取一条记录@Service@TransactionalpublicclassPersonServiceBeanimplementsPersonService{

privateJdbcTemplatejdbcTemplate;

@Resource publicvoidsetDataSource(DataSourcedataSource){ this.jdbcTemplate=newJdbcTemplate(dataSource); } publicPersongetPerson(Integerid){ RowMapperrowMapper=newRowMapper(){ publicObjectmapRow(ResultSetrs,introwNum)throwsSQLException{ Personperson=newPerson(); person.setId(rs.getInt("id")); person.setName(rs.getString("name")); returnperson; } }; return(Person)jdbcTemplate.queryForObject("select*frompersonwhereid=?", newObject[]{id},newint[]{java.sql.Types.INTEGER},rowMapper); }}

使用JdbcTemplate获取一条记录@Service

使用JdbcTemplate获取多条记录@Service@TransactionalpublicclassPersonServiceBeanimplementsPersonService{

privateJdbcTemplatejdbcTemplate;

@Resource publicvoidsetDataSource(DataSourcedataSource){ this.jdbcTemplate=newJdbcTemplate(dataSource); } publicList<Person>getPersons(){ RowMapperrowMapper=newRowMapper(){ publicObjectmapRow(ResultSetrs,introwNum)throwsSQLException{ Personperson=newPerson(); person.setId(rs.getInt("id")); person.setName(rs.getString("name")); returnperson; } }; returnjdbcTemplate.query("select*fromperson",rowMapper); }}

使用JdbcTemplate获取多条记录@Service

事务传播属性REQUIRED:业务方法需要在一个事务中运行。如果方法运行时,已经处在一个事务中,那么加入到该事务,否则为自己创建一个新的事务。NOT_SUPPORTED:声明方法不需要事务。如果方法没有关联到一个事务,容器不会为它开启事务。如果方法在一个事务中被调用,该事务会被挂起,在方法调用结束后,原先的事务便会恢复执行。REQUIRESNEW:属性表明不管是否存在事务,业务方法总会为自己发起一个新的事务。如果方法已经运行在一个事务中,则原有事务会被挂起,新的事务会被创建,直到方法执行结束,新事务才算结束,原先的事务才会恢复执行。MANDATORY:该属性指定业务方法只能在一个已经存在的事务中执行,业务方法不能发起自己的事务。如果业务方法在没有事务的环境下调用,容器就会抛出例外。SUPPORTS:这一事务属性表明,如果业务方法在某个事务范围内被调用,则方法成为该事务的一部分。如果业务方法在事务范围外被调用,则方法在没有事务的环境下执行。Never:指定业务方法绝对不能在事务范围内执行。如果业务方法在某个事务中执行,容器会抛出例外,只有业务方法没有关联到任何事务,才能正常执行。NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中.如果没有活动事务,则按REQUIRED属性执行.它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效

事务传播属性REQUIRED:业务方法需要在一个事务中运

Connectionconn=null;try{conn.setAutoCommit(false);Statementstmt=conn.createStatement();

stmt.executeUpdate("updatepersonsetname='888'whereid=1");

Savepointsavepoint=conn.setSavepoint();try{

conn.createStatement().executeUpdate("updatepersonsetname='222'wheresid=2");}catch(Exceptionex){

conn.rollback(savepoint);}stmt.executeUpdate("deletefrompersonwhereid=9");mit();stmt.close();}catch(Exceptione){conn.rollback();}finally{try{ if(null!=conn&&!conn.isClosed())conn.close();}catch(SQLExceptione){e.printStackTrace();}}}

Connectionconn=null;

数据库系统提供了四种事务隔离级数据库系统提供了四种事务隔离级别供用户选择。不同的隔离级别采用不同的锁类型来实现,在四种隔离级别中,Serializable的隔离级别最高,ReadUncommited的隔离级别最低。大多数据库默认的隔离级别为ReadCommited,如SqlServer,当然也有少部分数据库默认的隔离级别为RepeatableRead,如MysqlReadUncommited:读未提交数据(会出现脏读,不可重复读和幻读)。ReadCommited:读已提交数据(会出现不可重复读和幻读)RepeatableRead:可重复读(会出现幻读)Serializable:串行化脏读:一个事务读取到另一事务未提交的更新新据。不可重复读:在同一事务中,多次读取同一数据返回的结果有所不同。换句话说就是,后续读取可以读到另一事务已提交的更新数据。相反,“可重复读”在同一事务中多次读取数据时,能够保证所读数据一样,也就是,后续读取不能读到另一事务已提交的更新数据。幻读:一个事务读取到另一事务已提交的insert数据。

数据库系统提供了四种事务隔离级数据库系统提供了四种事务隔演讲完毕,谢谢观看!演讲完毕,谢谢观看!Spring手册上海浦东软件园·职业技能培训Spring手册上海浦东软件园·职业技能培训

Spring是什么Spring是一个开源的控制反转(InversionofControl,IoC)和面向切面(AOP)的容器框架.它的主要目得是简化企业开发.

Spring是什么Spring是一个开源的控制反转(In

IOC控制反转publicclassPersonServiceBean{

privatePersonDaopersonDao=new

PersonDaoBean();

publicvoidsave(Personperson){personDao.save(person);}}PersonDaoBean是在应用内部创建及维护的。所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转。

IOC控制反转publicclassPerson

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

privatePersonDaopersonDao;

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

publicPersonServiceBean(PersonDaopersonDao){this.personDao=personDao;}

publicvoidsave(Personperson){personDao.save(person);}}所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中。

依赖注入(DependencyInjection)当我

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

可以使用容器提供的众多服务,如:事务管理服务、消息服务等等。当我们使用容器管理事务时,开发人员就不再需要手工控制事务.也不需处理复杂的事务传播。容器提供单例模式支持,开发人员不再需要自己编写实现代码。容器提供了AOP技术,利用它很容易实现如权限拦截、运行期监控等功能。容器提供的众多辅作类,使用这些类能够加快应用的开发,如:JdbcTemplate、HibernateTemplate。Spring对于主流的应用框架提供了集成支持,如:集成Hibernate、JPA、Struts等,这样更便于应用的开发。ControllerServiceDAO

为何要使用Spring至少在我看来,在项目中引入spri

使用Spring的好处当使用spring时,我们可以使用容器提供的众多服务

使用Spring的好处

如果使用Spring,我们就不再需要手工控制事务Hibernate的事务操作:publicvoidsave(){ Sessionsession=sessionFactory.getCurrentSession();

session.beginTransaction(); Infoinfo=newInfo("传智播客");info.setContent("国内实力最强的java培训机构");session.save(info);

session.getTransaction().commit();}JDBC的事务操作:

Connectionconn=null;try{.......

conn.setAutoCommit(false);Statementstmt=conn.createStatement();stmt.executeUpdate("updatepersonwherename='叶天'");

mit();.....

}catch(Exceptione){

conn.rollback();}finally{conn.close();}

如果使用Spring,我们就不再需要手工控制事务Hib

另外,如果使用spring,我们也不需要处理复杂的事务传播行为publicvoidpayment(){Bean1.update();//更新金额Bean2.save();//记录操作日志}如果我们不使用Spring,针对下面这两种业务需求,我们该如何做?第1种可能的业务需求:要求Bean1.update()和Bean2.save()在同一个事务中执行。第2种可能的业务需求:要求不管Bean1.update()的事务是否成功,都需要记录操作日志。publicclassBean1{

publicvoidupdate(){//注意:下面省略了一些代码 Connectionconn=null; conn.setAutoCommit(false);

Statement.executeUpdate(“updateaccountsetamount=?whereid=?");

}}publicclassBean2{

publicvoidsave(){//注意:下面省略了一些代码 Connectionconn=null; conn.setAutoCommit(false);

Statement.executeUpdate(“insertintoLog(content)values(?)");

}}

另外,如果使用spring,我们也不需要处理复杂的事务

使用Spring,不再需要我们处理复杂的事务传播行为使用Spring,我们只需要通过声明式的事务属性配置就可以轻松地实现这两种业务需求1.要求Bean1.update()和Bean2.save()的在同一个事务中执行2.要求不管Bean1.update()的事务是否成功,都需要记录日志。@Transactional(propagation=Propagation.Required)publicvoidpayment(){Bean1.update();//更新金额Bean2.save();//记录日志}

publicclassBean1{@Transactional(propagation=Propagation.Required)

publicvoidupdate(){

executeUpdate(“updateaccountsetamount=?whereid=?");

}}publicclassBean2{

@Transactional(propagation=Propagation.RequiresNew)

publicvoidsave(){ executeUpdate(“insertintoLog(content)values(?)");}}

使用Spring,不再需要我们处理复杂的事务传播行为使用

轻量级与重量级概念的划分经常会有同学问到spring属于轻量级框架,还是重量框架?其实划分一个应用是否属于轻量级还是重量级,主要看它使用了多少服务.使用的服务越多,容器要为普通java对象做的工作就越多,必然会影响到应用的发布时间或者是运行性能.对于spring容器,它提供了很多服务,但这些服务并不是默认为应用打开的,应用需要某种服务,还需要指明使用该服务,如果应用使用的服务很少,如:只使用了spring核心服务,那么我们可以认为此时应用属于轻量级的,如果应用使用了spring提供的大部分服务,这时应用就属于重量级。目前EJB容器就因为它默认为应用提供了EJB规范中所有的功能,所以它属于重量级。

轻量级与重量级概念的划分经常会有同学问到spring属于

使用Spring需要的jar

使用Spring需要的jar

spring的配置文件模版

spring的配置文件模版

编写spring配置文件时,不能出现帮助信息

编写spring配置文件时,不能出现帮助信息

实例化spring容器实例化Spring容器常用的两种方式:方法一:在类路径下寻找配置文件来实例化容器ApplicationContextctx=newClassPathXmlApplicationContext(newString[]{"beans.xml"});方法二:在文件系统路径下寻找配置文件来实例化容器ApplicationContextctx=newFileSystemXmlApplicationContext(newString[]{“d:\\beans.xml“});Spring的配置文件可以指定多个,可以通过String数组传入。

实例化spring容器实例化Spring容器常用的两种方

从spring容器中得到bean当spring容器启动后,因为spring容器可以管理bean对象的创建,销毁等生命周期,所以我们只需从容器直接获取Bean对象就行,而不用编写一句代码来创建bean对象。从容器获取bean对象的代码如下:ApplicationContextctx=newClassPathXmlApplicationContext(“beans.xml”);OrderServiceservice=(OrderService)ctx.getBean("personService");

从spring容器中得到bean当spring容器启动后

使用dom4j读取spring配置文件

使用dom4j读取spring配置文件

三种实例化bean的方式1.使用类构造器实例化<beanid=“orderService"class="cn.itcast.OrderServiceBean"/>2.使用静态工厂方法实例化<beanid="personService"class="cn.itcast.service.OrderFactory"factory-method="createOrder"/>publicclassOrderFactory{ publicstaticOrderServiceBeancreateOrder(){ returnnewOrderServiceBean(); }}3.使用实例工厂方法实例化:<beanid="personServiceFactory"class="cn.itcast.service.OrderFactory"/><beanid="personService"factory-bean="personServiceFactory"factory-method="createOrder"/>publicclassOrderFactory{ publicOrderServiceBeancreateOrder(){ returnnewOrderServiceBean(); }}

三种实例化bean的方式1.使用类构造器实例化

Bean的作用域.singleton

在每个SpringIoC容器中一个bean定义只有一个对象实例。默认情况下会在容器启动时初始化bean,但我们可以指定Bean节点的lazy-init=“true”来延迟初始化bean,这时候,只有第一次获取bean会才初始化bean。如:

<beanid="xxx"class="cn.itcast.OrderServiceBean"lazy-init="true"/>如果想对所有bean都应用延迟初始化,可以在根节点beans设置default-lazy-init=“true“,如下:<beansdefault-lazy-init="true“...>.prototype

每次从容器获取bean都是新的对象。

.request.session.globalsession

Bean的作用域.singleton

指定Bean的初始化方法和销毁方法指定Bean的初始化方法和销毁方法<beanid="xxx"class="cn.itcast.OrderServiceBean"init-method="init"destroy-method="close"/>

指定Bean的初始化方法和销毁方法指定Bean的初始化注入依赖对象基本类型对象注入:<beanid="orderService"class="cn.itcast.service.OrderServiceBean"> <constructor-argindex=“0”type=“java.lang.String”value=“xxx”/>//构造器注入 <propertyname=“name”value=“zhao/>//属性setter方法注入</bean>注入其他bean:方式一<beanid="orderDao"class="cn.itcast.service.OrderDaoBean"/><beanid="orderService"class="cn.itcast.service.OrderServiceBean"> <propertyname="orderDao"ref="orderDao"/></bean>方式二(使用内部bean,但该bean不能被其他bean使用)<beanid="orderService"class="cn.itcast.service.OrderServiceBean"> <propertyname="orderDao"> <beanclass="cn.itcast.service.OrderDaoBean"/> </property></bean>注入依赖对象基本类型对象注入:集合类型的装配publicclassOrderServiceBean{ privateSet<String>sets=newHashSet<String>(); privateList<String>lists=newArrayList<String>(); privatePropertiesproperties=newProperties(); privateMa

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论