反射优化

要优化首先得知道瓶颈点,如下代码进行测试。

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectTest {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User("zhengbiyu");
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000; i++) {
            user.getName();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("未反射总耗时:" + (endTime - startTime) + "ms");
        startTime = System.currentTimeMillis();
        Method getMethod = null;
        for (int i = 0; i < 1000000; i++) {
            getMethod = User.class.getDeclaredMethod("getName");
        }
        endTime = System.currentTimeMillis();
        System.out.println("反射获取方法信息总耗时:" + (endTime - startTime) + "ms");
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000; i++) {
            getMethod.invoke(user);
        }
        endTime = System.currentTimeMillis();
        System.out.println("反射调用方法总耗时:" + (endTime - startTime) + "ms");
    }
}
class User {
    private String name;

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

 可以看出瓶颈点在于获取方法信息。

缓存字段、方法信息

那我们可以将获取到的方法信息进行一个缓存,就不用每次获取了。mybatis框架就是这样进行优化的:

org.apache.ibatis.reflection.Reflector

/**
 * This class represents a cached set of class definition information that
 * allows for easy mapping between property names and getter/setter methods.
 *
 * @author Clinton Begin
 */
public class Reflector {

  private final Class<?> type;
  private final String[] readablePropertyNames;
  private final String[] writeablePropertyNames;
 //对set、get、构造方法进行缓存
private final Map<String, Invoker> setMethods = new HashMap<String, Invoker>(); private final Map<String, Invoker> getMethods = new HashMap<String, Invoker>(); private final Map<String, Class<?>> setTypes = new HashMap<String, Class<?>>(); private final Map<String, Class<?>> getTypes = new HashMap<String, Class<?>>(); private Constructor<?> defaultConstructor; private Map<String, String> caseInsensitivePropertyMap = new HashMap<String, String>(); public Reflector(Class<?> clazz) { type = clazz; addDefaultConstructor(clazz); addGetMethods(clazz); addSetMethods(clazz); addFields(clazz); readablePropertyNames = getMethods.keySet().toArray(new String[getMethods.keySet().size()]); writeablePropertyNames = setMethods.keySet().toArray(new String[setMethods.keySet().size()]); for (String propName : readablePropertyNames) { caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName); } for (String propName : writeablePropertyNames) { caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName); } } private void addDefaultConstructor(Class<?> clazz) { Constructor<?>[] consts = clazz.getDeclaredConstructors(); for (Constructor<?> constructor : consts) { if (constructor.getParameterTypes().length == 0) { if (canAccessPrivateMethods()) { try { constructor.setAccessible(true); } catch (Exception e) { // Ignored. This is only a final precaution, nothing we can do. } } if (constructor.isAccessible()) { this.defaultConstructor = constructor; } } } } private void addGetMethods(Class<?> cls) { Map<String, List<Method>> conflictingGetters = new HashMap<String, List<Method>>(); Method[] methods = getClassMethods(cls); for (Method method : methods) { if (method.getParameterTypes().length > 0) { continue; } String name = method.getName(); if ((name.startsWith("get") && name.length() > 3) || (name.startsWith("is") && name.length() > 2)) { name = PropertyNamer.methodToProperty(name); addMethodConflict(conflictingGetters, name, method); } } resolveGetterConflicts(conflictingGetters); } }

 动态生成类

通过字节码生成,生成一个类,类的方法实现是直接调用原方法。编译、加载类。

public interface ObjectFieldGetter {

    /**
     * 获取对应的param对应的filedName属性值
     *
     * @param params
     * @param filedName
     * @return
     */
    Object get(Object[] params, String filedName);
}

生成类示例:

public class DynamicObjectFieldGetterImpl序号 implements ObjectFieldGetter {

    @Override
    public Object get(Object[] args, String filedName) {
        return ((com.xxx.xxx.原对象类限定名) args[0]).getPin();
    }
}

编译加载动态生成的类。

posted on 2024-06-25 17:06  zhengbiyu  阅读(5)  评论(0编辑  收藏  举报