Spring AOP + Transaction

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_35221883/article/details/89790261

Spring AOP + transaction

spring aop的底层原理就是动态代理。
spring transaction依靠于aop

弥补基础知识

静态代理and JDK动态代理
cglib代理
spring aop所使用的代理为jdk动态代理或cglib动态代理,如果不使用spring aop的话(手写aop ),可以考虑:当使用单例时尽量使用cglib动态代理(创建对象时效率低但运行效率高),相反,当使用多例时尽量使用jdk动态代理(创建对象时效率高但运行效率低)。

实现AOP的几种方法
  • 徒手写(静态代理、jdk动态代理、cglib动态代理)
  • xml配置文件实现(spring自动在jdk动态代理和cglib动态代理之间切换)
  • 注解@Aspect实现(spring自动在jdk动态代理和cglib动态代理之间切换)
spring aop思想

切面内(代理类)包含切点(匹配)和增强(方法)。

编写步骤(注解版)

1、引入aop命名空间
xmlns:context=“http://www.springframework.org/schema/context
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
2、开启aop注解 <aop:aspectj-autoproxy />
3、创建切面(加注解@Aspect)
4、编写增强(函数)
5、编写切点 (哪些业务方法使用函数)
@Pointcut(“execution(* cn.itcast.e_aop_anno…(…))”) 指定切入点表达式
@Before(“pointCut_()”) 前置通知: 目标方法之前执行
@After(“pointCut_()”) 后置通知:目标方法之后执行(始终执行)
@AfterReturning(“pointCut_()”) 返回后通知: 执行方法结束前执行(异常不执行)
@AfterThrowing(“pointCut_()”) 异常通知: 出现异常时候执行
@Around(“pointCut_()”) 环绕通知: 环绕目标方法执行

示例

@Component
@Aspect//指定为切面类
public class AOP {
    // 指定切入点表达式,拦截哪个类的哪些方法
    @Pointcut("execution(* aa.*.*(..))")
    public void pt() {
    }

    @Before("pt()")
    public void begin() {
        System.out.println("开始事务");
    }

    @After("pt()")
    public void close() {
        System.out.println("关闭事务");
    }
}

切点详解啊!

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)

?号代表0或1,可以不写
“*”号代表任意类型,0或多
方法参数为…表示为可变参数

示例

<!-- 【拦截所有public方法】 -->
        <!--<aop:pointcut expression="execution(public * *(..))" id="pt"/>-->

        <!-- 【拦截所有save开头的方法 】 -->
        <!--<aop:pointcut expression="execution(* save*(..))" id="pt"/>-->

        <!-- 【拦截指定类的指定方法, 拦截时候一定要定位到方法】 -->
        <!--<aop:pointcut expression="execution(public * cn.itcast.g_pointcut.OrderDao.save(..))" id="pt"/>-->

        <!-- 【拦截指定类的所有方法】 -->
        <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.*(..))" id="pt"/>-->

        <!-- 【拦截指定包,以及其自包下所有类的所有方法】 -->
        <!--<aop:pointcut expression="execution(* cn..*.*(..))" id="pt"/>-->

        <!-- 【多个表达式】 -->
        <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) || execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->
        <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) or execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->
        <!-- 下面2个且关系的,没有意义 -->
        <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) &amp;&amp; execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->
        <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) and execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->

        <!-- 【取非值】 -->
        <!--<aop:pointcut expression="!execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->
编写步骤(xml版)

1、引入aop命名空间
xmlns:context=“http://www.springframework.org/schema/context
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
2、配置aop(切面、切点和增强)

示例

	<!--切面类-->
    <bean id="aop" class="aa.AOP"/>
    
    <!--AOP配置-->
    <aop:config >
        <!--定义切入表达式,拦截哪些方法-->
        <aop:pointcut id="pointCut" expression="execution(* aa.*.*(..))"/>
        <!--指定切面类是哪个-->
        <aop:aspect ref="aop">
            <!--指定来拦截的时候执行切面类的哪些方法-->
            <aop:before method="begin" pointcut-ref="pointCut"/>
            <aop:after method="close" pointcut-ref="pointCut"/>
        </aop:aspect>
    </aop:config>

spring transaction

spring事务分为编码式(与业务代码依偎在一起)和声明式(基于aop)。
声明式也包括注解方式和xml配置方式

注解@Transactional

1、开启事务注解驱动 <tx:annotation-driven />
2、配置事务控制的数据源
3、添加@Transactional到特定的方法或类上

@Transactional注解的属性列举啊!
属性名 说明
name 当在配置文件中有多个 TransactionManager , 可以用该属性指定选择哪个事务管理器。
propagation 事务的传播行为,默认值为 REQUIRED。
isolation 事务的隔离度,默认值采用 DEFAULT。
timeout 事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务。
read-only 指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。
rollback-for 用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指定,各类型之间可以通过逗号分隔。
no-rollback- for 抛出 no-rollback-for 指定的异常类型,不回滚事务。

propagation配置的是一个事务的传播性问题,所谓事物传播性就是被调用者的事务与调用者的事务之间的关系
propagation有那些配置项罗列出来啊!

示例

<tx:annotation-driven />

<bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>

那就关注这一点吧

Spring事务管理器的接口是org.springframework.transaction.PlatformTransactionManager,通过这个接口,Spring为各个平台如JDBC、Hibernate等都提供了对应的事务管理器,但是具体的实现就是各个平台自己的事情了。
不同的事务管理器管理不同的数据资源DataSource

help列举一下哈
DataSourceTransactionManager --> JDBC
HibernateTransactionManager --> Hibernate
JpaTransactionManager --> JPA
JtaTransactionManager --> 原生API事务

猜你喜欢

转载自blog.csdn.net/weixin_35221883/article/details/89790261
今日推荐