java 反射

现有一个需求要求公共类的main方法要根据传入的参数实例化某个具体类,并调用该类的都有的一个方法getJob做某些操作。

参数类型

  • 参数1 自定义job类型的名称
  • 参数2 输出路径
  • 参数3,4,5... 输入路径*/
enter description here

方案一 暴力反射,获取类方法直接调用

package com.bigdata.AIDoctorGuide.job;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Arrays;

import org.apache.hadoop.mapreduce.Job;

//使用反射来构建自定义的job对象,并且调用getJob方法获取MR的job实例

public class JobRunner {
    public static void main(String[] args) throws Exception {

        if (args.length < 3) {
            System.err.println("参数输入不争取,,,");
            System.exit(1);
        }
        
        String className = args[0];
        String outputPath = args[1];
        String[] inputPaths = Arrays.copyOfRange(args, 2, args.length);
        
        Class cz = Class.forName(className);
        //获取该类的构造方法
        Constructor[] constructors = cz.getConstructors();
        //规则规定:该类只有一个非默认的构造方法,并且接受两个参数,
        //一个参数为string 另一个为string[] 如RecordReimburseJob类构造方法
        Constructor constructor = constructors[0];
        
        //方案一 很暴力
        Object testInstance = constructor.newInstance(outputPath,inputPaths);
        Job testJob = null;
//      Method[] methods = cz.getMethods();
//      for (Method method : methods) {
//          if (method.getName().equals("getJob")) {
//              testJob = (Job)method.invoke(testInstance);
//              break;
//          }
//      }
        
        Method getJobMethod = cz.getMethod("getJob");
        if (getJobMethod != null) {
            testJob = (Job)getJobMethod.invoke(testInstance);
        }
        long startTime = System.currentTimeMillis();
        boolean flag = testJob.waitForCompletion(true);
        if (flag == true) {
            long endTime = System.currentTimeMillis();
            System.out.println("job 运行成功,耗时 :" + (endTime - startTime)/1000 + "秒");
        }else {
            System.out.println("程序运行失败,请检查日志");
        }
    }

}

方案二 定义一个公共接口类GenericJob,所有使用JobRunner运行的类都需要实现该接口

package com.bigdata.AIDoctorGuide.job;

import org.apache.hadoop.mapreduce.Job;

public interface GenericJob {
    public Job getJob() throws Exception;
}

使用接口类接受实例化后的具体类,然后直接调用getJob方法,然后进行后续的操作

package com.bigdata.AIDoctorGuide.job;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Arrays;

import org.apache.hadoop.mapreduce.Job;

//使用反射来构建自定义的job对象,并且调用getJob方法获取MR的job实例

public class JobRunner {
    public static void main(String[] args) throws Exception {
        /*
         * 参数1 自定义job类型的名称
         * 参数2  输出路径
         * 参数3,4,5... 输入路径*/
        if (args.length < 3) {
            System.err.println("参数输入不争取,,,");
            System.exit(1);
        }
        
        String className = args[0];
        String outputPath = args[1];
        String[] inputPaths = Arrays.copyOfRange(args, 2, args.length);
        
        Class cz = Class.forName(className);
        //获取该类的构造方法
        Constructor[] constructors = cz.getConstructors();
        //规则规定:该类只有一个非默认的构造方法,并且接受两个参数,
        //一个参数为string 另一个为string[] 如RecordReimburseJob类构造方法
        Constructor constructor = constructors[0];
        
        GenericJob jobObject = (GenericJob)constructor.newInstance(outputPath,inputPaths);
        
        Job recordJob = jobObject.getJob();
        
        long startTime = System.currentTimeMillis();
        boolean flag = recordJob.waitForCompletion(true);
        if (flag == true) {
            long endTime = System.currentTimeMillis();
            System.out.println("job 运行成功,耗时 :" + (endTime - startTime)/1000 + "秒");
        }else {
            System.out.println("程序运行失败,请检查日志");
        }
        
    }

}

你可能感兴趣的:(java 反射)