跟开振学习Spring AOP第三篇:为什么要用AOP
Posted ykzhen2015
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了跟开振学习Spring AOP第三篇:为什么要用AOP相关的知识,希望对你有一定的参考价值。
前面两篇,我们通过动态代理介绍了可以通过约定来编程,也实现了一个简单的Spring AOP的例子。但是至今我还没有告诉你为什么要使用AOP,是不是很杯具??那为什么需要AOP呢?
AOP首先要处理那些OOP不能处理的问题,比如我们现在有学生报名,那么需要在数据库插入学生信息和学生证信息了吧,好吧,在Java中学生信息和学生证信息都可以用OOP(面向对象设计),而在数据库编程中它们都应该放在一个事务中,要么同时成功,要么同时失败,这就是一个典型的事务问题,我们来看这个图。
好了,我们发现数据库事务是不能用OOP去设计的,但是它贯穿了学生信息和学生证信息两个(OOP)对象,事务就是一个横切面(所以叫切面编程 AOP),贯穿了多个对象,它需要协作多个对象之间的关系。也就是为什么需要切面编程的原因。
AOP能减少大量的代码。
对于JDBC而开发,你是不是对那些繁琐的try...catch....finally...心生厌倦?我们先来看看mybatis是如何插入数据库的
public int insertUser(User user)
SqlSession sqlSession = null;
int result = 0;
try
// 获取数据库连接资源
sqlSession = MyBatisUtils.getSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
result = userDao.insertUser(user);
// 提交事务
sqlSession.commit();
catch (Exception ex)
// 回滚事务
sqlSession.rollback();
// 异常处理
finally
// 关闭资源
if (sqlSession != null)
sqlSession.close();
return result;
好了,上面有数据库连接的闭合,也有事务的提交和回滚,初学者的代码大部分都类似(或者出现错误 )。
通过Spring AOP,你要对上面的代码说NO了!!因为我们可以写成这样:
@Autowired
UserDao userDao = null;
......
@Transactional
public int insertUser(User user)
return userDao.insertUser(user);
好了,所有的功能有已经完成了,如果你还是初学者,你是不是十分惊讶呢?你可以看到没有数据库资源的闭合,也没有事务的代码,仅仅只有@Transactional这个注解的使用而已。这样你的工作主要的是业务,而不是数据库资源和事务的代码的开发。这样的神奇也是AOP给你的,好吧,我们再来看看约定的情况,下面是AOP给你的约定:
当遇到@Transactional注解的时候,该方法将启用事务机制:
- 数据库资源在前置通知(before)完成——切面自己完成
- 然后反射inserUser方法
- 如果发生异常回滚事务(afterThrowing方法)——切面自己完成
- 如果不发生异常提交事务(afterReturning方法)——切面自己完成
- 最后释放事务资源——切面自己完成
让我们用一张图说明一下:
于是你可以看到,你只是需要完成这个流程中的一部分,而不需要全部完成,没有数据库资源的闭合,也没有事务的代码,你只需要完成业务逻辑,然后Spring将你的业务逻辑通过AOP织入到流程中。
所以你的代码就很简单了,你只需要使用@Transactional告诉Spring你需要事务,那么它就将你的方法织入到约定的数据库AOP流程中,这样你的任务就少了很多,你主要完成的是业务逻辑就可以了,这样代码就更加清晰和易维护了。
小结:
通过上面,我们可以看到AOP可以解决OOP处理不了的事情,尤其是数据库事务,这是企业关注的核心内容之一;
通过数据库的事务代码,我们可以看到通过AOP,可以将你开发的业务逻辑织入到数据库约定好的流程中,这样你的代码就简单多了。
从上面两条我们可以知道:
AOP允许我们将通用的流程和代码抽取出来,单独实现,然后给出约定的流程,从而把后续开发者的代码织入约定的流程,从而减少大量重复的工作,使得开发者的工作更为简单,这样业务逻辑就更清晰,代码工作量就更少,尤其是我们核心内容——数据库事务更是如此。
以上是关于跟开振学习Spring AOP第三篇:为什么要用AOP的主要内容,如果未能解决你的问题,请参考以下文章
设计思想 - 第三篇 为什么要用Wrappers来创建QueryWrapper?
设计思想 - 第三篇 为什么要用Wrappers来创建QueryWrapper?