设为首页 加入收藏

TOP

我们为什么要使用 AOP(四)
2017-10-16 10:29:33 】 浏览:10513
Tags:我们 为什么 使用 AOP
的作用,这里以实际场景作为例子。

第一个例子,我们知道MyBatis的事务默认是不会自动提交的,因此在编程的时候我们必须在增删改完毕之后调用SqlSession的commit()方法进行事务提交,这非常麻烦,下面利用AOP简单写一段代码帮助我们自动提交事务(这段代码我个人测试过可用):

/**
 * @author 五月的仓颉http://www.cnblogs.com/xrq730/p/7003082.html
 */
public class TransactionHandler {

    public void commit(JoinPoint jp) {
        Object obj = jp.getTarget();
        if (obj instanceof MailDao) {
            Signature signature = jp.getSignature();
            if (signature instanceof MethodSignature) {
                SqlSession sqlSession = SqlSessionThrealLocalUtil.getSqlSession();                
                
                MethodSignature methodSignature = (MethodSignature)signature;
                Method method = methodSignature.getMethod();
                 
                String methodName = method.getName();
                if (methodName.startsWith("insert") || methodName.startsWith("update") || methodName.startsWith("delete")) {
                    sqlSession.commit();
                }
                
                sqlSession.close();
            }
        }
    }
    
}

这种场景下我们要使用的aop标签为<aop:after>,即切在方法调用之后。

这里我做了一个SqlSessionThreadLocalUtil,每次打开会话的时候,都通过SqlSessionThreadLocalUtil把当前会话SqlSession放到ThreadLocal中,看到通过TransactionHandler,可以实现两个功能:

  1. insert、update、delete操作事务自动提交
  2. 对SqlSession进行close(),这样就不需要在业务代码里面关闭会话了,因为有些时候我们写业务代码的时候会忘记关闭SqlSession,这样可能会造成内存句柄的膨胀,因此这部分切面也一并做了

整个过程,业务代码是不知道的,而TransactionHandler的内容可以充分再多处场景下进行复用。

第二个例子是权限控制的例子,不管是从安全角度考虑还是从业务角度考虑,我们在开发一个Web系统的时候不可能所有请求都对所有用户开放,因此这里就需要做一层权限控制了,大家看AOP作用的时候想必也肯定会看到AOP可以做权限控制,这里我就演示一下如何使用AOP做权限控制。我们知道原生的Spring MVC,Java类是实现Controller接口的,基于此,利用AOP做权限控制的大致代码如下(这段代码纯粹就是一段示例,我构建的Maven工程是一个普通的Java工程,因此没有验证过):

/**
 * @author 五月的仓颉http://www.cnblogs.com/xrq730/p/7003082.html
 */
public class PermissionHandler {

    public void hasPermission(JoinPoint jp) throws Exception {
        Object obj = jp.getTarget();
        
        if (obj instanceof Controller) {
            Signature signature = jp.getSignature();
            MethodSignature methodSignature = (MethodSignature)signature;
            
            // 获取方法签名
            Method method = methodSignature.getMethod();
            // 获取方法参数
            Object[] args = jp.getArgs();
            
            // Controller中唯一一个方法的方法签名ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;
            // 这里对这个方法做一层判断
            if ("handleRequest".equals(method.getName()) && args.length == 2) {
                Object firstArg = args[0];
                if (obj instanceof HttpServletRequest) {
                    HttpServletRequest request = (HttpServletRequest)firstArg;
                    // 获取用户id
                    long userId = Long.parseLong(request.getParameter("userId"));
                    // 获取当前请求路径
                    String requestUri = request.getRequestURI();
                    
                    if(!PermissionUtil.hasPermission(userId, requestUri)) {
                        throw new Exception("没有权限");
                    }
                }
            }
        }
        
    }
    
}

毫无疑问这种场景下我们要使用的aop标签为<aop:before>。这里我写得很简单,获取当前用户id与请求路径,根据这两者,判断该用户是否有权限访问该请求,大家明白意思即可。

后记

文章演示了从原生代码到使用AOP的过程,一点一点地介绍了每次演化的优缺点,最后以实际例子分析了AOP可以做什么事情。

首页 上一页 1 2 3 4 下一页 尾页 4/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇这些年,安放在我工位上的那些书 下一篇Redis 和 Memcached 的区别

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目