spring框架AOP(声明式事务控制)

整合Hibernate事务控制

1.1 了解事务

我们一般说的事务是来源于关系数据库,当有数据持久化需求时一般都需要事务控制。

关系数据库:支持事务控制,mysql数据库存储引擎为InnoDB支持事务,存储引擎为MyIsam不支持事务。

jdbc:支持事务控制,设置CommitAuto(false)

Hibernate:支持事务,使用session.beginTransaction(),session.getTransaction().commit()提交事务

spring如果控制事务:由于使用hibernatespringHibernatesession进行管理,支持事务。

1.2 HibenateTemplate

spring针对持久层框架提供了模板类封装数据库操作方法:

1、可以简化数据访问的开发

2、支持事务控制,springHibernatesession进行管理

spring提供了很多模板:

1JdbcTemplate,针对jdbc操作数据库模板,相当于DbUtil

2HibernateTemplate,针对Hibernate操作数据库模板。

1.3 加入jar

spring-orm-4.2.4.RELEASE.jarspring针对orm框架整合包

spring-tx-4.2.4.RELEASE.jarspring提供事务管理的包

spring-jdbc-4.2.4.RELEASE.jarspring提供jdbc操作方法包,此包为事务控制的基础包

1.4 测试HibenateTemplate

1.4.1dao

dao实现类继承HibenrateDaoSupport(选择hibernate对应版本,一般选第5版)

1.4.2 配置dao

 

<bean id="customerTestDao" class="cn.itcast.crm.dao.impl.CustomerTestDaoImpl">

</bean>

运行报错:

'sessionFactory' or 'hibernateTemplate' is required

由于dao继承HibernateDaoSupport运行需要'sessionFactory''hibernateTemplate'

解决:

'sessionFactory' or 'hibernateTemplate'注入到dao中。

<!-- 加载db.properties配置文件 -->

         <context:property-placeholder location="classpath:db.properties"/>

         <!--  -->

         <bean id="customerTestDao" class="cn.itcast.crm.dao.impl.CustomerTestDaoImpl">

          <property name="hibernateTemplate" ref="hibernateTemplate"/>

         </bean>

         

         <!-- hibernateTemplate,依赖了sessionFactory -->

         <bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">

          <property name="sessionFactory" ref="sessionFactory"></property>

         </bean>

         <!-- 配置 sessionFactory,依赖dataSource数据源(数据库连接池)-->

         <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">

          <!-- 数据源 -->

          <property name="dataSource" ref="dataSource"/>

         </bean>

         

         <!-- spring对  数据源进行管理 -->

         <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">

          <!-- mysql的驱动包 -->

          <property name="driverClass" value="${jdbc.driver}" />

          <!-- 连接数据库url -->

<property name="jdbcUrl" value="${jdbc.url}" />

<property name="user" value="${jdbc.username}" />

<property name="password" value="${jdbc.password}" />

         </bean>

报错:

Unable to locate persister: cn.itcast.crm.domain.CstCustomer

CstCustomer不是一个被hibenate管理的实体类型。

解决:

在创建SessionFacotry时候加载Hibenate 映射文件:

以上是和hibernate框架进行整合,

2基于aop使用声明式事务控制

2.1 什么是aop

当前service开发中问题:

每个需要进行事务控制的service代码中事务控制部分代码重复的代码,将这些事务控制重复的代码抽取出来。

解决方法:

采用spring aop面向切面编程对上边的代码进行抽取

AOP Aspect Oriented Programing 面向切面编程。Spring1.2 版本开始支持AOP编程 (面向切面编程 )。

采用aop的方法对类代码切面编程,通过横向抽取方法将service中的事务控制的代码抽取出来。

2.2 aop的原理

aop面向切面编程的原理就是代理:

1、静态代理

采用一些工具类对原来的类生成一个代理类,代理类以.class存在

2、动态代理(重点,spring基于动态代理实现aop

 在运行中,通过反射生成类的代理对象,在代理对象中对原来的对象进行增强。

spring采用动态代理的技术包括:

1基于接口生成代理对象(重点)

根据接口方法生成代理对象,对原来的代理对象进行增强

使用jdk提供反射实现

2基于类生成代理对象

根据类生成一个子类(代理对象),在代理对象(子类)中对父类进行增强。

使用CGLib实现

编写原始类:

public interface CustomerServiceAop {

public void insertCustomer(CstCustomer cstCustomer,CstCustomerDetail cstCustomerDetail) ;

}

 了解jdkcglib区别

jdk:基于接口生成代理对象

cglib:基于类生成代理对象

spring底层使用jdkcglib,如果原始对象实现了一个接口,spring使用jdk,否则 使用cglib生成代理。

AOP联盟

AOP联盟出一套aop的标准。

aop联盟的jar包:

aop术语:

Pointcut(切入点):确定在哪个方法上增强,一个类有多个切点

 

Advice(通知/增强):在切点上进行增强,包括:前置增强、后置增强、抛出异常增强

Target(目标对象):对目标对象进行增强,生成代理对象

 

Proxy(代理):对目标对象进行增强,生成代理对象

Weaving(织入):生成代理的时机(过程)

1动态代理织入,在运行期为目标类生成代理对象

2、编译期织入

Aspect(切面): 包括切点和增强,面向哪个切点进行增强(编程)。

AspectJ语法(切点语法):

通过语法配置切入点:

切入点:方法,哪个/哪个/方法

表达式包括两部分:函数名和操作参数。

例子:execution(* cn.itcast.spring.service.impl.*.*(..))  匹配cn.itcast.spring.service.impl包下所有类的所有方法(任意形参),任意返回值。

 增强

AspectJ支持的增强类型:

n Before 前置增强/通知,相当于BeforeAdvice

n AfterReturning 后置增强/通知,相当于AfterReturningAdvice

n Around 环绕增强/通知,相当于MethodInterceptor

n AfterThrowing抛出增强/通知,相当于ThrowAdvice

After 最终finally增强/通知,不管是否异常,该通知都会执行

 下面就开始逐层配置:

dao:

还是用上面写好的继承hibernamteTemplate

 service

 

事务管理器

applicatoinContext-transaction.xml

配置增强(实现事务 管理)

加入约束:

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:aop="http://www.springframework.org/schema/aop" 

xmlns:tx="http://www.springframework.org/schema/tx" 

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd 

http://www.springframework.org/schema/context 

http://www.springframework.org/schema/context/spring-context.xsd 

http://www.springframework.org/schema/aop 

http://www.springframework.org/schema/aop/spring-aop.xsd 

http://www.springframework.org/schema/tx  

http://www.springframework.org/schema/tx/spring-tx.xsd">

<!-- 切面

包括:切点和增强

 -->

<aop:config>

<!-- 使用aop:advisor配置切面,和 tx:advice配置使用实现事务控制

advice-ref :指定引用增强

-->

<aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.itcast.crm.service.impl.*.*(..))"/>

</aop:config>

猜你喜欢

转载自www.cnblogs.com/jingyukeng/p/10241647.html