如何在运行时为动态对象调用方法?

时间:2019-04-17 08:28:10

标签: java hibernate reflection orm byte-buddy

我的问题很简单,我们可以在运行时调用类的方法,而不必在运行时专门使用反射,在这种情况下,我们必须使用ORM而不是面向对象的形式从数据库中加载大量数据原始ResultSet。

现在我的组织使用的ORM是专有的,我在其代码中看到的将数据从数据库加载到POJO的过程是它通过调用getters和setters方法(如下面的代码片段)使用反射来设置字段的值(这是典型的解决方案和大多数ORM都遵循相同的条件

// somewhere inside my ORM
Object obj = pojo.newInstance();// pojo a Class instance wrapping up original POJO mapping of Table in db

Class type =pojo.getMethod("get"+StringUtils.capitalize(fieldName),Class[0]).getReturnType();

Method m = pojo.getMethod("set"+StringUtils.capitalize(fieldName), new Class[] { paramType });

m.invoke(obj, new Object[] { value });

现在,这里的主要问题是Class类的getMethod,如果我们在rt.jar中检查它的实现,则可以在Class.class(在rt.jar中)的下面找到代码

  private static Method searchMethods(Method[] methods,
                                        String name,
                                        Class<?>[] parameterTypes)
    {
        Method res = null;
        String internedName = name.intern();
        for (int i = 0; i < methods.length; i++) {
            Method m = methods[i];
            if (m.getName() == internedName
                && arrayContentsEq(parameterTypes, m.getParameterTypes())
                && (res == null
                    || res.getReturnType().isAssignableFrom(m.getReturnType())))
                res = m;
        }

        return (res == null ? res : getReflectionFactory().copyMethod(res));
    }

此searchMethods在那里,由getMethod内部调用以查找对象的方法。

这是一个性能负担,因为如果在pojo中有80个字段,那么我们将有近80个getter和80个setter,在最坏的情况下,它必须迭代方法数组以进行比较160次(getter的80个和setter的80个)< / p>

现在,如果我必须选择6个字段,那么它必须扫描方法数组12次以获取getter和setter,如果我确实选择了20个字段,则依此类推。

now how to solve this performance issue while maintaining 3 key points
 1. Performance (in terms of iterations)
 2. Less memory usage 
 3. Re-usability

在JPA中,我们必须根据需求创建不同的DTO,例如,如果在视图的一侧有6个字段,那么我们必须创建具有6个字段作为参数的构造函数,如果我们需要20个,则必须创建具有在同一个DTO中有20个字段,或者我们必须用这20个字段创建整个新的DTO,而在上述方法中,不需要构造函数,不需要新类,并且通过方法调用POJO被用于从动态文件选择到更新特定字段的各处。 >

现在,我不想在POJO中创建多个DTO或多个构造函数,而是想调用getter和setter方法,而又不会通过反射降低对象初始化的性能。

那么还有另一种方法可以调用POJO的即时getter和setter方法,而无需在运行时进行反思,特别是在ORM API的用例中?通过此操作,我必须继续使用现有的ORM,而不要切换到Hibernate + JPA

0 个答案:

没有答案