ONGL表达式执行的所有操作都是根据表达式解析得到的。 例如:
“对象名.方法名”表示调用指定对象的指定方法;“@[类的完全限定名]@[静态方法或者静态字段]”表示调用指定类的静态方法或访问静态字段;OGNL表达式还可以完成变量赋值、操作集合等操作。OGNL表达式指定了具体的操作,而root对象指定了需要操作的对象。 ###3、OgnlContext(上下文对象) OgnaContext类实现了Map接口,所以OgnaContext对象中可以存放除了root对象之外的其他对象。
使用OGNL表达式操作非root对象时,需要使用#前缀,而操作root对象则不需要使用#前缀Mybatis为了提升OGNL表达式的性能,通过OgnlCache中的expressionCache(静态成员,ConcurrentHashMap<String, Object>)来对解析后的OGNL表达式进行缓存。
/** * ognl表达式缓存 */ private static final Map<String, Object> expressionCache = new ConcurrentHashMap<>(); private OgnlCache() { // Prevent Instantiation of Static Class } public static Object getValue(String expression, Object root) { try { //NOTE: 创建OgnlContext对象,OgnlClassResolver替代了OGNL中原有的DefaultClassResolver,其主要功能是通过Resources来定位资源 Map context = Ognl.createDefaultContext(root, MEMBER_ACCESS, CLASS_RESOLVER, null); //NOTE: 使用OGNL执行表达式 return Ognl.getValue(parseExpression(expression), context, root); } catch (OgnlException e) { throw new BuilderException("Error evaluating expression '" + expression + "'. Cause: " + e, e); } } private static Object parseExpression(String expression) throws OgnlException { Object node = expressionCache.get(expression); if (node == null) { //NOTE: 缓存中没有对应数据,解析表达式并以experssion为key,解析结果为value缓存 node = Ognl.parseExpression(expression); expressionCache.put(expression, node); } return node; }未完待续~,接下来会通过SQL执行过程中,在通过SqlSourceBuilder构建SqlSource时,是如何用Ognl表达式来判断<if test=“expression”>中的expression表达式的?