刨根问底--ognl-set设置数据
cookqq ›博客列表 ›struts源码分析

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

2013-02-25 08:49:38.0|分类: struts源码分析|浏览量: 1751

摘要: 《刨根问底--ognl--get获取数据》

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









一键分享文章

分类列表

  • • struts源码分析
  • • flink
  • • struts
  • • redis
  • • kafka
  • • ubuntu
  • • zookeeper
  • • hadoop
  • • activiti
  • • linux
  • • 成长
  • • NIO
  • • 关键词提取
  • • mysql
  • • android studio
  • • zabbix
  • • 云计算
  • • mahout
  • • jmeter
  • • hive
  • • ActiveMQ
  • • lucene
  • • MongoDB
  • • netty
  • • flume
  • • 我遇到的问题
  • • GRUB
  • • nginx
  • • 大家好的文章
  • • android
  • • tomcat
  • • Python
  • • luke
  • • android源码编译
  • • 安全
  • • MPAndroidChart
  • • swing
  • • POI
  • • powerdesigner
  • • jquery
  • • html
  • • java
  • • eclipse
  • • shell
  • • jvm
  • • highcharts
  • • 设计模式
  • • 列式数据库
  • • spring cloud
  • • docker+node.js+zookeeper构建微服务
版权所有 cookqq 感谢访问 支持开源 京ICP备15030920号
CopyRight 2015-2018 cookqq.com All Right Reserved.