第4.45课 上课 AOP, Spring事务

4_45

AOP

 AOP是什么?

AOP是什么,能做什么?

AOP是Aspect Orient Programing,面向切面编程(面向方面编程).

 

AOP能做什么?

考虑如下场景:项目开发出来之后,有一天,客户要求为方法A、B、C……等每个方法,都增加一个日志功能.

 

比较原始的解决方案: 先定义一个代表日志功能的通用方法,然后依次打开A、B、C……等每个方法,然后增加调用通用方法.

程序员需要手动去修改方法A、方法B、方法C……等每个方法.

过了一段时间,客户又要求为方法A、B、C……等每个方法,都增加一个权限检查的功能,程序员又需要依次修改每个方法

过了一段时间,客户又要求为方法A、B、C……等每个方法……

 

如果用传统的做法,每次为项目增加一个具有通用性质的横切处理,程序员就需要把所有的方法都修改一遍,因此非常复杂.

 

此时需要一种技术:

1. 既可为项目中每个方法都增加这种通用性质的横切处理.

2. 不需要程序员去修改任何的代码.

 

为了达到这个目的,解决方案是:让框架来帮我们修改源代码,如果让框架帮我们为方法A、方法B、方法C……来增加具有

通用性质的横切处理,这种框架就是AOP.

 AspectJ(AOP框架)

AspectJ是一个基于Java语言的AOP框架,提供了强大的AOP功能,其他很多AOP框架都借鉴或采纳其中的一些思想.

 AOP编程的概念

AOP编程的概念:

Aspect: 切面、方面.

Joinpoint: 连接点.程序执行过程中一个明确的点.

Advice: 增强处理.就是Aop框架在切入点插入(织入)这一段通用处理代码.

切入点Pointcut:可以插入增强处理的连接点.简而言之,当某个连接点满足指定要求时,

该连接点将被添加增强处理,该连接点也就变成了切入点.

 

引入introduce in:添加方法或field到被处理的类.Spring允许引入新的接口到任何被处理的对象.

例如,你可以使用一个引入,使任何对象实现 IsModified接口,以此来简化缓存.

 

目标对象target Object:被AOP框架进行增强处理的对象,也被称为被增强的对象.

如果AOP框架是通过运行时代理来实现的,那这个对象将是一个被代理的对象.

 

AOP代理:AOP框架创建的对象,简单地说,代理就是对目标对象的加强.

Spring中的AOP代理可以是JDK动态代理,也可以是CGLIB代理,

前者为实现接口的目标对象的代理,后者为不实现接口的目标对象的代理.

 

织入Weaving: 将增强处理添加到目标对象中、并创建一个被增强的对象(AOP代理)的过程就是织入.

织入有两种实现方式: 编译时增强(例如AspectJ)和运行时增强(例如CGLIB).

Spring和其他纯Java AOP框架一样,在运行时完成织入.

 

 

 依赖jar包

  aopalliance-1.0.jar

  aspectjweaver-1.8.5.jar

Spring事务

Spring事务:

Spring事务,需要在所有的业务逻辑组件中都需要织入—这就是AOP发挥作用的地方.

Spring的声明式事务就是基于AOP实现,通过AOP的实现,即可将不同业务逻辑组件与不同的事务控制代码分离.

 

 

 

 

策略模式:

我们要做一件事情,但做这件事情有很种实现算法,目前程序不知道选择哪种算法,或为了兼容以可能新增的算法,此时可考虑策略模式.

我们要做事务控制,不同的持久化技术,对应的事务控制代码是不同的,目前程序不知道选择哪种事务代码,

或以后可能要换其他的事务控制代码.(持久层技术变了,事务控制代码就要跟着变).

 

策略模式的实现:

1.定义一个策略接口,让我们的程序面向策略接口编程,从而让程序与实现算法分离.

Spring提供了PlatformTransactionManager接口.

 

2.针对不同的算法,为该接口提供不同的实现类.

DataSourceTransactionManager:针对JDBC技术的事务实现.

HibernateTransactionManager:针对Hibernate技术的事务实现.

JpaTransactionManager:针对Jpa技术的事务实现.

JtaTransactionManager:针对JtaTransactionManager技术的事务实现.

 

3.需要一个Context类,Context会为程序“智能”选择一个策略实现类.

ApplicationContext。——所谓智能,程序员在beans.xml文件中配置实现类,ApplicationContext选择该实现类.

 PlatformTransactionManager事务策略接口

  DataSourceTransactionManager针对JDBC技术的事务实现

  JtaTransactionManager针对Jta技术的事务实现

  HibernateTransactionManager针对Hibernate技术的事务实现

  JdoTransactionManager针对Jdo技术的事务实现

  JpaTransactionManager针对Jpa技术的事务实现

 配置事务管理器

<!-- 配置事务管理器transactionManager -->

<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"

p:sessionFactory-ref="sessionFactory"/>

 声明式事务

声明式事务,无需程序员写代码,直接配置即可.

  依赖jar包

   aopalliance-1.0.jar

   aspectjweaver-1.8.5.jar

  配置tx命名空间

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

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

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

  aop切面(切业务层)

<!-- 定义事务管理器(声明式的事务) -->

<bean id="transactionManager"

class="org.springframework.orm.hibernate5.HibernateTransactionManager">

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

</bean>

<tx:advice id="txAdvice" transaction-manager="transactionManager">

<tx:attributes>

<!--如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务-->

<tx:method name="*" propagation="REQUIRED" />

</tx:attributes>

</tx:advice>

<!-- 把事务Advice织入到哪些切入点(AOP事务切面) -->

<aop:config>

<!-- 定义切入点(切入业务层) -->

<aop:pointcut id="interceptorPointCuts"

expression="execution(* org.oa.service..*.*(..))" />

<!-- 将事务Advice运用到指定的切入点 -->

<aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointCuts" />

</aop:config>

   声明式事务advice配置

<!-- 声明式事务advice配置 -->

<tx:advice id="txAdvice" transaction-manager="transactionManager">

<!-- 配置事务属性 -->

<tx:attributes>

<!-- set开头的方法,用只读事务(只能做查询) -->

<tx:method name="set*" read-only="true"/>

<!-- get开头的方法,用只读事务(只能做查询) -->

<tx:method name="get*" read-only="true"/>

<!-- 剩余的所有方法,有事务可以做CUD [R] propagation(传播性) isolation(隔离性) -->

<tx:method name="*" read-only="false" propagation="REQUIRED" isolation="DEFAULT"/>

</tx:attributes>

</tx:advice>

 

 

--------------------------------------------------------------------

<!-- 定义事务管理器(声明式的事务) -->

<bean id="transactionManager"

class="org.springframework.orm.hibernate5.HibernateTransactionManager">

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

</bean>

<tx:advice id="txAdvice" transaction-manager="transactionManager">

<tx:attributes>

<tx:method name="*" propagation="REQUIRED" />

</tx:attributes>

</tx:advice>

    事务属性

     read-only="true"只读事务

     read-only="false"不是只读事务

     propagation="REQUIRED"事务传播性

如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中.(这是最常见的选择)

     isolation="DEFAULT"事务隔离性

使用数据库默认的事务隔离级别

     rollback-for出现什么异常回滚

     no-rollback-for出现什么异常不回滚

   配置aop命名空间

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

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

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

   aop事务切面配置

<!-- 把事务Advice织入到哪些切入点(AOP事务切面) -->

<aop:config>

<!-- 定义切入点(切入业务层) -->

<aop:pointcut id="interceptorPointCuts"

expression="execution(* org.oa.service..*.*(..))" />

<!-- 将事务Advice运用到指定的切入点 -->

<aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointCuts" />

</aop:config>

  annotation注解

   tx:annotation-driven

<!-- 开启annotation注解事务 -->

<tx:annotation-driven transaction-manager="transactionManager"/>

   @Transactional()事务注解

// 事务注解

@Transactional(readOnly=false, // 不是只读事务

isolation=Isolation.DEFAULT, // 事务隔离性

propagation=Propagation.REQUIRED) // 事务传播性

    写在业务类上这个类中所有方法都起作用

    写在业务类的方法上只有这个方法起作用

 编程式事务(了解)

编程式事务,需要程序员自己写代码.

posted on 2018-01-31 22:34  東風★破  阅读(122)  评论(0)    收藏  举报

导航