加入收藏 | 设为首页 | 会员中心 | 我要投稿 开发网_开封站长网 (http://www.0378zz.com/)- 科技、AI行业应用、媒体智能、低代码、办公协同!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

警惕,MyBatis的size()方法竟然有坑!

发布时间:2019-09-19 10:41:01 所属栏目:MySql教程 来源:http://h5ip.cn/aJgJ Mybatis是一个
导读:副标题#e# 来源:http://h5ip.cn/aJgJ Mybatis是一个开源的轻量级半自动化ORM框架,使得面向对象应用程序与关系数据库的映射变得更加容易。MyBatis使用xml描述符或注解将对象与存储过程或SQL语句相结合。Mybatis最大优点是应用程序与Sql进行解耦,sql语句是

invokeMethod方法代码

  1. public static Object invokeMethod(Object target, Method method, Object[] argsArray) throws InvocationTargetException, IllegalAccessException { 
  2.         boolean wasAccessible = true; 
  3.         if(securityManager != null) { 
  4.             try { 
  5.                 securityManager.checkPermission(getPermission(method)); 
  6.             } catch (SecurityException var6) { 
  7.                 throw new IllegalAccessException("Method [" + method + "] cannot be accessed."); 
  8.             } 
  9.         } 
  10.  
  11.         if((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) && !(wasAccessible = method.isAccessible())) { 
  12.             method.setAccessible(true); (1) 
  13.         } 
  14.  
  15.         Object result = method.invoke(target, argsArray); (3) 
  16.         if(!wasAccessible) { 
  17.             method.setAccessible(false); (2) 
  18.         } 
  19.  
  20.         return result; 
  21.     } 

问题出现在method实际上是一个共享变量,也就是例子中的

  1. public int java.util.Collections$SingletonList.size() 

方法

当第一个线程t1至(1)行代码允许method方法可以被调用,第二个线程t2执行至(2)将method的方法设置为不可以访问。接着t1又开始执行到(3)行的时候就会发生该异常。这是一个很典型的同步问题。Ognl2.7已经修复了该问题,因为ognl源码是直接打包内嵌在mybatis包中,mybatis3.3.0版本中也已经进行了修复升级。(划重点)

  1. public static Object invokeMethod(Object target, Method method, Object[] argsArray) throws InvocationTargetException, IllegalAccessException { 
  2.         boolean syncInvoke = false; 
  3.         boolean checkPermission = false; 
  4.         int mHash = method.hashCode(); 
  5.         synchronized(method) { 
  6.             if(_methodAccessCache.get(Integer.valueOf(mHash)) == null || _methodAccessCache.get(Integer.valueOf(mHash)) == Boolean.TRUE) { 
  7.                 syncInvoke = true; 
  8.             } 
  9.  
  10.             if(_securityManager != null && _methodPermCache.get(Integer.valueOf(mHash)) == null || _methodPermCache.get(Integer.valueOf(mHash)) == Boolean.FALSE) { 
  11.                 checkPermission = true; 
  12.             } 
  13.         } 
  14.  
  15.         boolean wasAccessible = true; 
  16.         Object result; 
  17.         if(syncInvoke) { 
  18.             synchronized(method) { 
  19.                 if(checkPermission) { 
  20.                     try { 
  21.                         _securityManager.checkPermission(getPermission(method)); 
  22.                         _methodPermCache.put(Integer.valueOf(mHash), Boolean.TRUE); 
  23.                     } catch (SecurityException var12) { 
  24.                         _methodPermCache.put(Integer.valueOf(mHash), Boolean.FALSE); 
  25.                         throw new IllegalAccessException("Method [" + method + "] cannot be accessed."); 
  26.                     } 
  27.                 } 
  28.  
  29.                 if(Modifier.isPublic(method.getModifiers()) && Modifier.isPublic(method.getDeclaringClass().getModifiers())) { 
  30.                     _methodAccessCache.put(Integer.valueOf(mHash), Boolean.FALSE); 
  31.                 } else if(!(wasAccessible = method.isAccessible())) { 
  32.                     method.setAccessible(true); 
  33.                     _methodAccessCache.put(Integer.valueOf(mHash), Boolean.TRUE); 
  34.                 } else { 
  35.                     _methodAccessCache.put(Integer.valueOf(mHash), Boolean.FALSE); 
  36.                 } 
  37.  
  38.                 result = method.invoke(target, argsArray); 
  39.                 if(!wasAccessible) { 
  40.                     method.setAccessible(false); 
  41.                 } 
  42.             } 
  43.         } else { 
  44.             if(checkPermission) { 
  45.                 try { 
  46.                     _securityManager.checkPermission(getPermission(method)); 
  47.                     _methodPermCache.put(Integer.valueOf(mHash), Boolean.TRUE); 
  48.                 } catch (SecurityException var11) { 
  49.                     _methodPermCache.put(Integer.valueOf(mHash), Boolean.FALSE); 
  50.                     throw new IllegalAccessException("Method [" + method + "] cannot be accessed."); 
  51.                 } 
  52.             } 
  53.  
  54.             result = method.invoke(target, argsArray); 
  55.         } 
  56.  
  57.         return result; 
  58.     } 

(编辑:开发网_开封站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读