在项目中有时候我们会使用到反射的功能,如果使用最原始的方法来开发反射的功能的话肯能会比较复杂,需要处理一大堆异常以及访问权限等问题。spring中提供了ReflectionUtils

这个反射的工具类,如果项目使用spring框架的话,使用这个工具可以简化反射的开发工作。

我们的目标是根据bean的名称、需要调用的方法名、和要传递的参数来调用该bean的特定方法。

下面直接上代码:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;

/**
 * Created with IntelliJ IDEA.
 * User: 焦一平
 * Date: 2015/6/15
 * Time: 18:22
 * To change this template use File | Settings | File Templates.
 */
@Service
public class ReInvokeService {
    @Autowired
    private SpringContextsUtil springContextsUtil;

    public void reInvoke(String beanName,String methodName,String[] params){
        Method method = ReflectionUtils.findMethod(springContextsUtil.getBean(beanName).getClass(), methodName, String.class, String.class, Boolean.class,String.class);
        Object[] param1 = new Object[3];
        param1[0]=params[0];
        param1[1]=params[1];
        param1[2]=true;
        ReflectionUtils.invokeMethod(method, springContextsUtil.getBean(beanName), param1);
    }
}

ReflectionUtils.findMethod()方法的签名是这样的:

public static Method findMethod(Class<?> clazz, String name, Class<?>… paramTypes)

依次需要传入 class对象、方法名、参数类型

SpringContextsUtil 这个工具类实现了 ApplicationContextAware接口,可以访问ApplicationContext的相关信息,代码如下:

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * Created with IntelliJ IDEA.
 * User: 焦一平
 * Date: 2015/6/15
 * Time: 18:36
 * To change this template use File | Settings | File Templates.
 */
@Component
public class SpringContextsUtil implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    public Object getBean(String beanName) {
        return applicationContext.getBean(beanName);
    }

    public <T> T getBean(String beanName, Class<T> clazs) {
        return clazs.cast(getBean(beanName));
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        this.applicationContext = applicationContext;
    }
}

Spring平台中,有不少东西值得学习,用好其工具类,也可以最大限度的简化代码。

org.springframework.util.ReflectionUtils是spring提供的反射工具类,使用它有以下好处:

  • 通常我们使用Java反射时,需要处理IllegalAccessException之类的又臭又多的检查异常,在国内大多数偏向于业务的编码中,99%情况都不会出现上述异常,而又需要写代码进行catch。使用Spring工具类,可以直接将其转换为RuntimeException,在业务中无需直接捕获。
  • 通过Spring提供的接口,可以对类中符合条件的一批接口或字段进行处理,可以最大限度的减少冗余的,类似的模板代码的编写。
    ReflectionUtils中的方法,分为以下几种类型:
  • find:通常是传入Class对象,以及字段名或方法名,查找对应的字段和方法
  • get:从一个字段中获取值
  • set:向字段中赋值
  • is:检查方法或字段是公有、私有还是静态
  • invoke:反射方式调用方法
  • doWith:通过模板的方式,批量处理方法内容

上述方法中,find,get,set,is和invoke容易理解,这里不再赘述。

doWith方法的目的,是提供一组模板方法,通过回调函数的方式,对于字段或方法进行批量调用或批量处理