现有一个需求要求公共类的main方法要根据传入的参数实例化某个具体类,并调用该类的都有的一个方法getJob
做某些操作。
参数类型
- 参数1 自定义job类型的名称
- 参数2 输出路径
- 参数3,4,5... 输入路径*/
方案一 暴力反射,获取类方法直接调用
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("参数输入不争取,<JobName>,<outputPath>,<inputPaths...>");
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("参数输入不争取,<JobName>,<outputPath>,<inputPaths...>");
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("程序运行失败,请检查日志");
}
}
}
网友评论