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控制事务 (方便)
-
在applicationContext.xml中配置好事务管理器,上面有配置方法
-
在applicationContext.xml中配置声明式事务标签,并指定事务管理器
-
<!--声明式事务,注解实现--> <!-- 告知spring,@Transactional在定制事务时,基于tx=DataSourceTransactionManager --> <tx:annotation-driven transaction-manager="tx"/>
-
在applicationContext.xml中配置好注解扫描,上面有配置方法
-
在想添加事务的方法上添加@Transactional注解即可
(事务控制应该在ServiceImpl层实现,而不是controller层)