SSM之AOP与事务
前言
这一节我们会终结spring
1. 简介
可以看出我们这里只有save有记录时间的功能
但是我们运行其他的也可能会有这个功能
这就是在不惊动原来的设计,源代码不变,添加功能
追加功能的就是切入点
2. AOP入门案例
2.1 分析
2.2 实现
1.导入坐标
context的包导入,AOP的包就自动导入了—》AOP开发是默认导入的
还要导入这个包
2.做好连接点(dao)
3.把功能性功能抽出来,单独做
- 定义切入点
先定义一个私有方法
这个方法pt就是一个切入点,描述的是update这个方法
5.绑定method这个共性功能和切入点pt的关系
但是还不能运行,因为这个类不受spring控制
变成bean了,但是不知道这个类是做AOP的
这样就知道是做AOP的了
但是还不行
因为配置类那里还不知道你在整个程序中是拿注解开发的AOP
这里我们只需要加两个东西
和
3. AOP工作流程
意思是我们只读取有切面的切入点
意思是我们最终运行的是一个代理对象,如何看代理对象呢
我们用第二个方法就可以看到代理对象了,第一个方法就看到表面的对象
4. AOP切入点表达式
4.1 语法格式
可以描述接口,也可以描述实现类,都是可以的
但是如果切入点太多,就写很多,就很麻烦了
4.2 通配符
两个点表示任意个参数
一个星表示一个参数
第三个是以service结尾的类或者子类的任意方法的任意参数,返回值任意
就是任意业务层接口
因为没有参数,所以无法AOP,就是正常调用update
两个点就是任意
这就是匹配任意的
这个就是匹配u开头的方法
()前面的是方法,在前面的是类,前面的前面就是包
这个就是给业务层所有的查询方法加AOP
4.3 书写格式
5. AOP通知类型
前置通知
后置通知
下面开始讲环绕,就是前后都有的那种
先直接这样写的话,原始操作都不见了
现在开始写select的
注意我们用around环绕的时候,原来有返回值的话,我们要在最后面把原始方法的返回值给扔出去
那我们的100哪去了,可以这样
注意外面那个函数的返回值最好写object
所以void的时候,函数around的返回值也可以写object
这两个有什么区别吗,AfterReturning是在没有抛异常的时候才会执行
了解即可
这个就是抛异常后才会执行的
常用的就是环绕通知
6. 测量业务层接口万次执行效率
现在开始写aop
第一要监管service所有的方法
在此之前要先把aop注解打开
就是@EnableAspectJAutoProxy
这个null主要是因为我们打印了
缺点就是不知道这是哪个方法的运行时间
Signature signature = pjp.getSignature();//原方法的签名信息
System.out.println(signature.getDeclaringType());
System.out.println(signature.getName());
这就找到了
7. AOP通知获取数据
主要就是获取原始操作的参数,返回值,异常
7.1 参数
这就是拿参数的方式
注意proceed可以传参数进去,传进去声明,参数就变了
7.2 返回值
主要我们看afterReturning怎么得到返回值
我们用ret接收返回值,然后还要利用注解来告诉我们要用ret来接收返回值
returning = "ret"中的ret就是参数名
然后就是jp必须在ret的前面,如果有jp的话
7.3 异常
主要是afterThroeing方法
这样就可以了
后面两个了解即可,主要掌握参数的
8. AOP总结
9. Spring事务简介
万一业务层有错呢
这个有错,但是这个只会减钱,不会加钱,所以不行
所以我们要同成功同失败
加上 @Transactional就表示开启事务了
这个一般不写在实现类上,一般写在接口上
第二就是在配置中配置一个事务管理器
//配置事务管理器,mybatis使用的是jdbc事务
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
dataSource是外部注入的
这样我们就可以使用这个事务管理器了
第三就是还要在spring中告诉我们用注解来做事务
@EnableTransactionManagement就是这个即可
因为我们在接口中transfer中开了事务了,所以这两个操作同成功同失败
但是我们写在接口上,那么这个接口的所有方法就都开事务了
然后这里还是不变的
因为是jdbc的事务,所以用的是datasource的事务管理器,不然用其他事务的话,就要换一个了
10. spring事务角色
注意jdbc的datasource必须和事务管理器的datasource是一样的
11. spring事务属性
11.1 事务配置
因为有些异常是不回滚的,所以我们要设置rollbackFor
比如这种异常就是不回滚的
运行时异常是会回滚的,非运行时异常就不会回滚,比如我们上面这个
这个的意思就是遇到了IOException这个异常就要回滚
11.2 案例:转账业务追加日志
为了让日志一定执行,所以我们用try catch,这样就算异常了,也会执行
然后两个service均开启了事务
运行一下
这下中间有了一个异常,但是我们并没有打印还是,为什么呢,因为日志记录和转账记录隶属于同一个事务,同成功同失败了
所以记不上日志
而我们要的就是日志的事务不要加入总的事务
我们在log的services上面添加上这个propagation = Propagation.REQUIRES_NEW
就表示它自己创建自己的事务,不会与他们统一一个事务
再来运行一下
这样我们就成功了,就算有异常我们还是一样的记录了
11.3 事务转播行为
在我们的代码中AccountServiceImpl是管理员,LogServiceImpl是协调员
总结
下一节开始讲springMVC