spring-aop-事务-注解开发-代理

1.spring + mybatis:

Aop流程:

提前定义好几个用于Aop的类

前置通知:新建MyBeForeAdvice类 实现 MethodBeforeAdvice,并实现其方法

后置通知:新建MyAfterAdvice类 实现 AfterReturningAdvice,并实现其方法

环绕通知:新建RoundAdvice类 实现 MethodInterceptor ,并实现其方法

异常通知:新建ExceptionAdvice类 实现 ThrowsAdvice , 并编写 ”afterThrowing“ 方法,如下:

 

public void afterThrowing(Exception ex){
    System.out.println("异常通知: my throws 异常通知辅助功能");
}

 

applicationContext.xml配置如下:

 

<!-- 目标 : 原始业务,自己的某个bean都行-->
<bean id="us" class="com.qf.service.UserServiceImpl" />

<!-- 通知:额外功能 -->
<!-- 前置通知类 -->
<bean id="before" class="com.qf.aop.MyBeforeAdvice"></bean>
<!-- 后置通知,在核心之后执行,如果核心有异常,则不执行 -->
<bean id="after" class="com.qf.aop.MyAfterAdvice"></bean>
<!-- 在核心中抛异常时,执行 -->
<bean id="throws" class="com.qf.aop.MyThrowsAdvice"></bean>
<!-- 环绕通知 -->
<bean id="mi" class="com.qf.aop.MyMethodInterceptor"></bean>

 

定义切入点,形成切面

 

<aop:config>
    <!-- 切入点【修饰符  返回值  包.类  方法名  参数表 】 -->
    <aop:pointcut id="pc_shine" expression="execution(* queryUsers())"/>
    <aop:pointcut id="pc_shine2" expression="execution(* deleteUser(..))"/>
    <aop:pointcut id="pc_shine3" expression="execution(* updateUser(..))"/>
    <aop:pointcut id="pc_shine4" expression="execution(* saveUser(..))"/>
    
    <!-- 组装 -->
    <aop:advisor advice-ref="before" pointcut-ref="pc_shine"/>
    <aop:advisor advice-ref="after" pointcut-ref="pc_shine2"/>
    <aop:advisor advice-ref="throws" pointcut-ref="pc_shine3"/>
    <aop:advisor advice-ref="mi" pointcut-ref="pc_shine4"/>
</aop:config>

 

根据表达式通配切入点:

语法 : execution(返回值类型 包名.方法名(参数包名.类型))

 

<aop:config>
    <!--匹配参数-->
    <aop:pointcut id="pc01" expression="execution(* *(com.qf.pojo.User))"/>
    <!--匹配任意方法(无参)-->
    <aop:pointcut id="pc02" expression="execution(* *())"/>
    <!--匹配方法名(任意参数)-->
    <aop:pointcut id="pc03" expression="execution(* saveUser(..))"/>
    <!--匹配返回值类型(任意参数)-->
    <aop:pointcut id="pc04" expression="execution(java.lang.Integer *(..))"/>
    <!--匹配类名(任意参数)-->
    <aop:pointcut id="pc05" expression="execution(* com.qf.service.UserServiceImpl.*(..))"/>
    <!--匹配包名(任意参数)-->
    <aop:pointcut id="pc06" expression="execution(* com.qf.service.*.*(..))"/>
    <!--匹配包名、以及子包名(任意参数)-->
    <aop:pointcut id="pc07" expression="execution(* com..*.*(..))"/>

    <!--组装-->
    <aop:advisor advice-ref="after" pointcut-ref="pc01"/>
</aop:config>

 

2.事务控制:

1.配置DataSourceTransactionManager事务管理器,其中持有DataSource,可以控制事 务功能(commit,rollback等)。

 

<!-- 1. 引入一个事务管理器,其中依赖DataSource,借以获得连接,进而控制事务逻辑 -->
<bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>

 

2.配置事务切面, 事务使用的规则

 

<!--aop在事务中的使用, 配置事务切面, 事务使用的规则-->
<tx:advice id="txManager" transaction-manager="tx">
    <tx:attributes>
        <!--规定哪些方法不需要事务(查询方法)propagation="SUPPORTS"  取消事务-->
        <tx:method name="find*" propagation="SUPPORTS"/>
        <tx:method name="query*" propagation="SUPPORTS"/>
        <tx:method name="select*" propagation="SUPPORTS"/>
        <tx:method name="get*" propagation="SUPPORTS"/>
        <!--规定哪些方法需要事务(增删改) rollback-for="Exception" 遇到异常执行回滚操作-->
        <tx:method name="insert*" rollback-for="Exception"></tx:method>
        <tx:method name="update*" rollback-for="Exception"></tx:method>
        <tx:method name="delete*" rollback-for="Exception"></tx:method>
    </tx:attributes>
</tx:advice>

 

3.将事务管理的Advice 切入需要事务的业务方法中

 

<!--使用AOP切入事务-->
<aop:config>
    <!--规定切点(某个方法,或匹配范围内的方法)-->
    <aop:pointcut id="pc" expression="execution(* com.qf.service.*.*(..))"/>
    <!--组织切面-->
    <aop:advisor advice-ref="txManager" pointcut-ref="pc"/>
</aop:config>

 

3.开启注解开发

 

<!--开启注解使用(扫描此包下的所有注解)-->
<context:component-scan base-package="com.qf"></context:component-scan>

 

@Autowhrid与@Resource的区别

一个接口只有一个实现类的时候,用@Autowhird

一个人接口有多个实现类的时候,

bean的注解后面应加上括号,例如@Service(value = “u2”)

注入时用@Resource(name = "u2"),而不是@Autowhird

@Controller 用在控制层的实现类上

@Service 用在service实现类上

@Repository 用在dao层的实现类上

@Component 用在其他需要被spring管理的bean上

 

@Value("${某个属性名}") //获取引入的properties文件内的某个属性,赋值给变量

private String ha;

 

4.使用注解@Transactional控制事务 (方便)

  1. 在applicationContext.xml中配置好事务管理器,上面有配置方法

  2. 在applicationContext.xml中配置声明式事务标签,并指定事务管理器

  3.  

    <!--声明式事务,注解实现-->
    <!-- 告知spring,@Transactional在定制事务时,基于tx=DataSourceTransactionManager -->
    <tx:annotation-driven transaction-manager="tx"/>
    

     

  4. 在applicationContext.xml中配置好注解扫描,上面有配置方法

  5. 在想添加事务的方法上添加@Transactional注解即可

(事务控制应该在ServiceImpl层实现,而不是controller层)

posted @ 2021-10-15 11:49  黄大虾  阅读(74)  评论(0编辑  收藏  举报