2013-02-25 08:49:38.0|分类: struts源码分析|浏览量: 1716
《刨根问底--ognl--get获取数据》详细的解释了。ognl获取数据的过程。ognl设置数据的过程和获取数据的过程大部分都想同,只是后面的几部有所不一样,所以步骤1到10参照《刨根问底--ognl--get获取数据》文章。 首先看一下整个流程图: 10、OgnlRuntime类中setMethodValue()代码: public static final boolean setMethodValue(OgnlContext context, Object target, String propertyName, Object value, boolean checkAccessAndExistence) throws OgnlException, IllegalAccessException, NoSuchMethodException, MethodFailedException, IntrospectionException { boolean result = true; Method m = getSetMethod(context, (target == null) ? null : target.getClass(), propertyName); if (checkAccessAndExistence) { if ((m == null) || !context.getMemberAccess().isAccessible(context, target, m, propertyName)) { result = false; } } if (result) { if (m != null) { Object[] args = objectArrayPool.create(value); try { callAppropriateMethod(context, target, target, m.getName(), propertyName, Collections.nCopies(1, m), args); } finally { objectArrayPool.recycle(args); } } else { result = false; } } return result; }注释:(1)getSetMethod获取person对象中的setName方法 (2)根据传进来的值创建一个参数数组args (3)调用callAppropriateMethod方法,执行setName方法 11、callAppropriateMethod()代码: public static Object callAppropriateMethod( OgnlContext context, Object source, Object target, String methodName, String propertyName, List methods, Object[] args ) throws MethodFailedException { Throwable reason = null; Object[] actualArgs = objectArrayPool.create(args.length); try { Method method = getAppropriateMethod( context, source, target, methodName, propertyName, methods, args, actualArgs ); if ( (method == null) || !isMethodAccessible(context, source, method, propertyName) ) { StringBuffer buffer = new StringBuffer(); if (args != null) { for (int i = 0, ilast = args.length - 1; i <= ilast; i++) { Object arg = args[i]; buffer.append((arg == null) ? NULL_STRING : arg.getClass().getName()); if (i < ilast) { buffer.append(", "); } } } throw new NoSuchMethodException( methodName + "(" + buffer + ")" ); } return invokeMethod(target, method, actualArgs); } catch (NoSuchMethodException e) { reason = e; } catch (IllegalAccessException e) { reason = e; } catch (InvocationTargetException e) { reason = e.getTargetException(); } finally { objectArrayPool.recycle(actualArgs); } throw new MethodFailedException( source, methodName, reason ); }注释:(1)形式参数List methods,这里为什么是list类型呢?也就是说这个方法可以有多个,为什么《刨根问底--ognl-get获取数据》中只有一个方法呢? 笔者的理解:java中方法重载的应用,规则:方法名称相同 方法的参数必须不同 参数个数不同 或 参数类型不同 方法的返回值类型可以相同,也可以不同。 (2)getAppropriateMethod()获取合适的方法,代码:
public static Method getAppropriateMethod( OgnlContext context, Object source, Object target, String methodName, String propertyName, List methods, Object[] args, Object[] actualArgs ) { Method result = null; Class[] resultParameterTypes = null; if (methods != null) { for (int i = 0, icount = methods.size(); i < icount; i++) { Method m = (Method)methods.get(i); Class[] mParameterTypes = getParameterTypes(m); if ( areArgsCompatible(args, mParameterTypes) && ((result == null) || isMoreSpecific(mParameterTypes, resultParameterTypes)) ) { result = m; resultParameterTypes = mParameterTypes; System.arraycopy(args, 0, actualArgs, 0, args.length); for (int j = 0; j < mParameterTypes.length; j++) { Class type = mParameterTypes[j]; if (type.isPrimitive() && (actualArgs[j] == null)) { actualArgs[j] = getConvertedType(context, source, result, propertyName, null, type); } } } } } if ( result == null ) { result = getConvertedMethodAndArgs( context, target, propertyName, methods, args, actualArgs ); } return result; }getAppropriateMethod()方法中主要遍历methods中的方法,查看遍历的方法中的参数类型和传进来的值的类型是否一致。返回合适的方法。 上面的过程中找到了合适的方法了,然后通过java反射机制执行该方法invokeMethod()。 |