spring-aop通知实现,事务实现

一 : spring-aop

(一) 概述
Aop是oop在编码结构上的补充, 研究的是同一层面的相同功能

横向开发

适用场景

  1. 事务管理
  2. 日志记录
  3. 性能统计
  4. 权限校验

(二) 概念
Target object : 目标对象, 需要被增强的对象
Join point : 连接点, 可以被增强的方法
Pointcut : 切入点, 确定要被增强的方法
Advice : 通知(建言), 具体的增强内容
Aspect : 切面, 切入点 + 通知 = 切面
Introduction : 引介, 可以动态的为目标对象添加属性或者是方法(特殊的通知)
Weaving : 织入, 运行期间动态的目标对象和切面结合起来的过程
AOP proxy : 动态代理

(三) 通知的类型
Before advice : 前置通知
After returning advice : 后置通知
After throwing advice : 异常通知
After (finally) advice : 最终通知
Around advice : 环绕通知

(四) Xml实现

  1. 添加依赖
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>5.2.6.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.6.RELEASE</version>
</dependency>
  1. 编写目标对象
@Service("killService")
public class KillerServiceImpl implements KillerService {
    @Override
    public void kill() {
        System.out.println("杀人");
    }
}
  1. 编写通知类
public class KillerAdvice {
    public void before(){
        System.out.println("前置..");
    }
    public void afterReturning(){
        System.out.println("后置...");
    }
    public void atfterThrowing(){
        System.out.println("异常...");
    }
    public void after(){
        System.out.println("最终...");
    }
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕前...");
        Object proceed = proceedingJoinPoint.proceed();
        System.out.println("环绕后...");
        return proceed;
    }   
}
  1. 织入(生成代理对象)
 <bean class="com.ujiuye.demo.service.impl.KillerServiceImpl" id="killerService"/>
    <bean class="com.ujiuye.demo.advice.KillerAdvice" id="killerAdvice"/>
    <aop:config>
        <aop:pointcut id="px" expression="execution(* *..*.kill(..))"/>
        <aop:aspect ref="killerAdvice">
            <aop:before method="before" pointcut-ref="px"/>
            <aop:after method="after" pointcut-ref="px"/>
            <aop:after-returning method="afterReturning" pointcut-ref="px"/>
            <aop:after-throwing method="atfterThrowing" pointcut-ref="px"/>
            <aop:around method="around" pointcut-ref="px"/>
        </aop:aspect>
    </aop:config>

5.测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class KillerTest {
    @Autowired
    private KillerService killerService;
    @Test
    public void test(){
        killerService.kill();
    }
}

(五) 注解实现

  1. 编写目标对象
    在这里插入图片描述
  2. 编写切面
    在这里插入图片描述
  3. 编写配置文件
    在这里插入图片描述
    (六) 切点表达式
    ( * )匹配任意个字符
    ( . )匹配一级包的路径
    ( . . )匹配一级或多级包路径, 如果放在传参列表中表示可变参数

二 : 声明式事务
(一) 概述
事务是操作数据的一个逻辑单元

事务的特性

  1. 原子性: 表示该操作是最小动作单元, 要么同时成功要么同时失败
  2. 隔离性: 事务之间互不干扰互不影响
  3. 一致性: 事务操作前后总数不变
  4. 持久性: 事务提交后, 将结果永久的保存下来

(二) Spring中的事务控制
编程式: 手动编写代码对事务的处理进行控制
声明式: 显示的标明该操作被事务管理了 --> spring来进行管理

声明式事务的底层是依赖AOP的, 也就是说在方法执行前开启事务, 方法执行完毕后进行事务的提交或者是回滚

优点: 将业务逻辑和事务管理分离, 使得我们只需要专注于业务逻辑即可
缺点: 事务管理的粒度, 只能是方法级

(三) 核心API

  1. platformTransactionManager
    获取事务的状态
    提交
    回滚

  2. transactionStatus
    是否是新事物
    是否有回滚点
    设置为回滚事务
    是否已完成

  3. transactionDefinition
    在这里插入图片描述
    在这里插入图片描述
    Propagation: 传播
    Isolation: 隔离
    readOnly: 只读
    Timeout: 超时

传播行为
在这里插入图片描述
在这里插入图片描述
可以简单的理解三者的关系:事务管理器通过读取事务定义参数进行事务管理,然后会产生一系列的事务状态

(四) 声明式事务的底层原理
在这里插入图片描述
(五) Xml实现

  1. 编写dao
@Repository
public class UserDaoImpl implements UserDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Override
    public void JianMoney(int from, double money) {
        jdbcTemplate.update("update user set money=money-? where id=?",money,from);
    }

    @Override
    public void AddMoney(int to, double money) {
        jdbcTemplate.update("update user money=money+? where id=?",money,to);
    }
}
  1. 编写service
@Service("userService")
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
    @Override
    public void updateMoney(int from, int to, double money) {
        userDao.JianMoney(from,money);
        int i=1/0;
        userDao.AddMoney(to,money);
    }
}

  1. 编写配置文件
	<context:component-scan base-package="com.ujiuye.demo"/>   
    <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///offcn?serverTimezone=UTC"/>
        <property name="username" value="root"/>
        <property name="password" value=""/>
    </bean>

    <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <tx:advice transaction-manager="transactionManager" id="interceptor">
        <tx:attributes>
            <tx:method name="updateMoney"/>
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="pc" expression="execution(* *..*.updateMoney(..))"/>
        <aop:advisor advice-ref="interceptor" pointcut-ref="pc"/>
    </aop:config>
  1. 测试
public class UserTest {
    @Autowired
    private UserService userService;
    @Test
    public void test(){
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
         userService = (UserService) applicationContext.getBean("userService");
         userService.updateMoney(1,2,500);
    }
}

(六) 注解实现

  1. 配置文件开启注解驱动
    <tx:annotation-driven/>
  2. 在需要事务管理的方法或者类上添加注解即可
    在这里插入图片描述
    添加在方法上表示该方法被事务管理
    添加在类上表示该类中的每个方法都被事务管理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值