刨根问底--ognl-set设置数据

刨根问底--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()。









转载于:https://my.oschina.net/winHerson/blog/110117

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值