一、Quartz簡介
1.quartz是開源且具有豐富特性的"任務調度庫",能夠集成於任何的java應用。
2.quartz主要分爲三大組件,分別是任務Job、觸發器Trigger以及調度器Scheduler。
quartz體系架構圖:
二、quartz三大組件簡介
1.任務Job:即想要調用的任務類,需要實現org.quartz.job接口,並重寫execute()方法,任務調度時會執行execute()方法。
2.觸發器Trigger:即執行任務的觸發器,當滿足什麼條件時會去執行你的任務Job,主要分爲根據時長間隔執行的SimpleTrigger和根據日曆執行的CronTrigger。
3.調度器Scheduler:即將Trigger和Job綁定之後,根據Trigger中的設定,負責進行Job調度的組件。
其它:
1.一個調度器可以讓多個觸發器Trigger和任務Job綁定,而一個任務Job實例只能和一個觸發器Trigger實例綁定,反過來也是如此。
三、案例入門
1.引入maven:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.2</version>
</dependency>
本文使用的是2.3.2版本,建議使用最新版本,如果需要日誌可自行引入。
2.測試代碼:
public class QuartzTest {
public static void main(String[] args) throws SchedulerException {
//1.調度器(Scheduler)
SchedulerFactory schedulerfactory = new StdSchedulerFactory();
//拿到調度器,調度器只需要一個即可,可以調度多個任務
Scheduler scheduler = schedulerfactory.getScheduler();
//2.Job實例(JobDetil)
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
.withIdentity("job", "default") //name:任務的名稱,group:分組名
.build();
//3.觸發器(Trigger)
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger", "default") //name:觸發器名稱,group:分組名
.startNow() //馬上執行一次,默認
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(20,2))//使用Simple觸發器,執行20次,間隔2秒
.build();
//4.讓Job和觸發器關聯
scheduler.scheduleJob(jobDetail,trigger);
//5.進行任務調度
scheduler.start();
}
public static class MyJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//打印當前時間
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = dateFormat.format(new Date());
System.out.println(date);
}
}
}
3.執行結果:
每兩秒打印一次時間。
3.步驟說明:
通過上文,可以大概知道quartz的操作大概分爲六步:
1.通過SchedulerFactory獲取一個任務調度器Scheduler
2.實現org.quartz.job接口,並重寫execute()方法爲自己需要的任務調度邏輯。
3.通過JobBuilder.newJob()構建一個JobDetail(Job實例對象),並設置對應參數。
4.通過TriggerBuilder.newTrigger()構建一個觸發器Trigger,並設置對應的參數。
5.通過Scheduler將JobDetail和Trigger綁定。
6.通過Scheduler的start()方法開始進行任務的調度。
四、參數傳遞
1.測試代碼:
public class QuartzTest {
public static void main(String[] args) throws SchedulerException{
//1.調度器(Scheduler)
SchedulerFactory schedulerfactory = new StdSchedulerFactory();
//拿到調度器,調度器只需要一個即可,可以調度多個任務
Scheduler scheduler = schedulerfactory.getScheduler();
//2.Job實例(JobDetil)
JobDataMap jobDetailMap = new JobDataMap();
jobDetailMap.put("name","xuye");
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
.withIdentity("job", "default") //name:任務的名稱,group:分組名
.usingJobData(jobDetailMap) //傳遞參數
.build();
//3.觸發器(Trigger)
JobDataMap triggerMap = new JobDataMap();
triggerMap.put("age",100);
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger", "default") //name:觸發器名稱,group:分組名
.usingJobData(triggerMap)
.startNow() //馬上執行一次,默認
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(1,2))//使用Simple觸發器,執行1次,間隔2秒
.build();
//4.讓調度器關聯Job和觸發器
scheduler.scheduleJob(jobDetail,trigger);
scheduler.start();
}
public static class MyJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//方式一,獲取JobDetail和Trigger傳遞的所有參數信息,使用此方式則不能對其進行設值。
JobDataMap jobDataMap = jobExecutionContext.getMergedJobDataMap();
//方式二,獲取JobDetail的Map參數
JobDataMap jobDetailMap = jobExecutionContext.getJobDetail().getJobDataMap();
//方式三,獲取Trigger的Map參數
JobDataMap triggerMap = jobExecutionContext.getTrigger().getJobDataMap();
System.out.println("getMergedJobDataMap()方法中能獲取到的key和value:\n"+getKeyAndValue(jobDataMap));
System.out.println("getJobDetail().getJobDataMap()方法中能獲取到的key和value:\n"+getKeyAndValue(jobDetailMap));
System.out.println("getTrigger().getJobDataMap()方法中能獲取到的key和value:\n"+getKeyAndValue(triggerMap));
}
private String getKeyAndValue(Map<String,Object> map) {
StringBuilder sb = new StringBuilder();
Set<Map.Entry<String, Object>> entries = map.entrySet();
for(Map.Entry<String, Object> entry : entries) {
sb.append(entry.getKey()+":"+entry.getValue().toString()+",");
}
return sb.toString();
}
}
}
2.執行結果:
3.說明:
1.通過使用 JobDataMap對象,在JobBuilder和TriggerBuilder中調用usingJobData方法將JobDataMap設置進去。
2.在org.quartz.job實現類中通過JobExecutionContext上文下環境獲取對應的參數,主要有以下3個方法,
1)jobExecutionContext.getMergedJobDataMap():
獲取JobBuilder和TriggerBuilder中兩個的Map參數,注意使用該方式只能獲取值,不能設置值,因爲是無效的。
2)jobExecutionContext.getJobDetail().getJobDataMap():
獲取JobDetail的Map參數,只能獲取JobDetail的。
3)jobExecutionContext.getTrigger().getJobDataMap():
獲取Trigger的Map參數,只能獲取Trigger的。
3.建議:如果只獲取值,則使用jobExecutionContext.getMergedJobDataMap(),如果需要獲取值,並把值傳遞到下一個任務調度中,請使用JobDetail或Trigger的對應參數。
4.jobExecutionContext.getMergedJobDataMap()不能設置原理說明:每次任務調度時,都會創建一個JobExecutionContext,而創建後會把JobDetail或Trigger的對應參數全部設置到一個新的Map中,如果進行設值,則下次創建的還是新創建一個Map,上一個JobExecutionContext的設值則變爲無效。
五、JobDataMap持久化
1.測試代碼:
public class QuartzTest {
public static void main(String[] args) throws SchedulerException{
//1.調度器(Scheduler)
SchedulerFactory schedulerfactory = new StdSchedulerFactory();
//拿到調度器,調度器只需要一個即可,可以調度多個任務
Scheduler scheduler = schedulerfactory.getScheduler();
//2.Job實例(JobDetil)
JobDataMap jobDetailMap = new JobDataMap();
jobDetailMap.put("count",0);
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
.withIdentity("job", "default") //name:任務的名稱,group:分組名
.usingJobData(jobDetailMap) //傳遞參數
.build();
//3.觸發器(Trigger)
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger", "default") //name:觸發器名稱,group:分組名
.startNow() //馬上執行一次,默認
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(20,2))//使用Simple觸發器,執行20次,間隔2秒
.build();
//4.讓調度器關聯Job和觸發器
scheduler.scheduleJob(jobDetail,trigger);
scheduler.start();
}
public static class MyJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//獲取JobDetail的Map參數
JobDataMap jobDetailMap = jobExecutionContext.getJobDetail().getJobDataMap();
Integer count = (Integer) jobDetailMap.get("count");
++count;
System.out.println("當前執行次數:"+count);
jobDetailMap.put("count",count);
}
}
}
2.執行結果:
3.說明:
1.我們想要統計執行次數,但每次獲取到的JobDetail參數Map都是新的。
2.如果想要JobDetail和Trigger的Map參數都是持久化,只需要在該Job實例的類上加上注@PersistJobDataAfterExecution即可。
3.修改如下:
4.新的測試結果:
5.JobDetail和Trigger的效果一致,Trigger代碼就不多寫,如果使用jobExecutionContext.getMergedJobDataMap(),只能獲取JobDetail和Trigger的Map數據,並不能設值,上文已經說明原理,可自行測試。
六、自動注入
1.測試代碼:
public class QuartzTest {
public static void main(String[] args) throws SchedulerException{
//1.調度器(Scheduler)
SchedulerFactory schedulerfactory = new StdSchedulerFactory();
//拿到調度器,調度器只需要一個即可,可以調度多個任務
Scheduler scheduler = schedulerfactory.getScheduler();
//2.Job實例(JobDetil)
JobDataMap jobDetailMap = new JobDataMap();
jobDetailMap.put("name","xuye");
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
.withIdentity("job", "default") //name:任務的名稱,group:分組名
.usingJobData(jobDetailMap) //傳遞參數
.build();
//3.觸發器(Trigger)
JobDataMap triggerMap = new JobDataMap();
triggerMap.put("age",100);
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger", "default") //name:觸發器名稱,group:分組名
.usingJobData(triggerMap)
.startNow() //馬上執行一次,默認
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(1,2))//使用Simple觸發器,執行1次,間隔2秒
.build();
//4.讓調度器關聯Job和觸發器
scheduler.scheduleJob(jobDetail,trigger);
scheduler.start();
}
public static class MyJob implements Job {
private String name;
private Integer age;
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("name:"+name+",age:"+age);
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
}
}
2.執行結果:
3.說明:
1.如需使用自動注入,只需要org.quartz.job實現類中提供和其對應的屬性名的set方法即可。
七、常用API
1.StdSchedulerFactory
方法名 | 說明 |
|
獲取一個調度器
|
|
初始化SchedulerFactory |
|
獲取所有的Scheduler |
2.Scheduler
方法名 | 說明 |
|
將JobDetail和Trigger綁定 |
|
通過JobKey立馬執行一個Job |
|
通過JobKey立馬執行一個Job,並傳遞參數 |
|
開始調度所有的任務,如果是暫停後調用則爲重啓 |
|
馬上關閉所有任務 |
|
是否等待任務執行完關閉,true等待,false不等待 |
|
暫停所有任務Job,通過start()方法重啓 |
|
通過JobKey暫停某個Job |
|
通過JobKey喚醒某個暫停的Job |
|
暫停某個Trigger的所有Job |
|
喚醒某個暫停的Trigger的Job |
3.JobBuilder
方法名 | 說明 |
|
加載Job的實例 |
|
設置該
|
|
傳遞參數,通過key和value |
|
傳遞參數,通過JobDataMap |
|
按照之前的參數設置,構建一個JobDetail |
4.JobDetail
方法名 | 說明 |
|
獲取該JobDetail的JobDataMap |
|
獲取該JobDetail的JobKey |
5.TriggerBuilder
方法名 | 說明 |
|
加載一個Trigger |
|
設置該
|
|
傳遞參數,通過key和value |
|
傳遞參數,通過JobDataMap |
|
關聯一個ScheduleBuilder,通常是SimpleScheduleBuilder或CronScheduleBuilder |
|
按照之前的參數設置,構建一個Trigger |
6.Trigger
方法名 | 說明 |
|
獲取該JobDetail的JobDataMap |
|
獲取下一次執行時間 |
|
獲取該Trigger的TriggerKey |
|
獲取結束時間 |
|
獲取開始時間 |
7.SimpleScheduleBuilder
方法名 | 說明 |
|
構建一個重複執行,按秒 |
|
重複執行,間隔按秒,並且執行一定的次數。 |
|
|
|
重複執行的次數,注意:如果是1,則執行2次,因爲運行立馬執行一次,以此類推。 |
8.CronScheduleBuilder
方法名 | 說明 |
|
根據cron表達式構建一個CronScheduleBuilder |
9.CronExpression
方法名 | 說明 |
|
校驗Cron表達式 |
|
構造函數,檢驗一個Cron表達式,如果不通過則拋出異常,該異常信息包含不通過的原因 |
八、Cron表達式
Cron表達式被用來配置CronTrigger實例,Cron表達式是一個由7個子表達式(第7個可以省略)組成的字符串。一般格式如下:* * * * * ?或* * * * * ?*,每個子表達式的代表一個日期細節,具體如下:
位置 | 說明 | 允許值 | 允許的特殊字符 |
1 | Seconds 秒 | 0-59 | , / * - |
2 | Minutes 分鐘 | 0-59 | , / * - |
3 | Hours 小時 | 0-23 | , / * - |
4 | Day-of-Month 月中的天 | 1-31 | , / * - ? L W C |
5 | Month 月 | 1-12或英文JAN-DEC | , / * - |
6 | Day-of-Week 週中的天 | 1-7或英文SUN-SAT | , / * - ? L C # |
7 | Year (optional field) 年(可選) | 1970-2099(一般不寫) | , / * - |
特殊字符含義說明:
字符 | 含義 |
,(逗號) | 表示多個值,如秒中使用逗號分隔5,10,20,則表示在5秒、10秒、20秒執行,理解爲或。 |
? | 表示不指定值,用於第四(月中的天)和第六位(週中的天),因爲第四位和第六位是衝突的,如果第四位有值則第六位必須爲?,反過來也是如此。 |
* | 表示所有可能的值,如果秒中使用*則表示60秒的每一秒都執行,小時上使用*則表示24小時的每個小時都執行。 |
- | 表示區間,如小時上用6-8,則表示6,7,8點都會執行。 |
/ | 表示間隔,如在秒中使用0/20,則表示每隔20秒執行一次。 |
# | 表示月中的第幾個周幾,如6#3,表示該月第三週的週五(國外的週日=我們的週一) |
W | 指定離給定日期最近的工作日(週一到週五) |
L | 用在第四位(月中的天)表示一個月中的最後一天,用在第六位(週中的天)表示該月最後一個星期X,如用在第六位6L,則表示這個月的最後一個週五 |
九、Trigger觸發器
Trigger觸發器主要分爲兩大類:Simple觸發器(通過SimpleScheduleBuilder關聯)和Cron觸發器(通過CronScheduleBuilder關聯),上文案例中已經介紹了SimpleScheduleBuilder的使用和API設置,下面看CronScheduleBuilder的使用。
1.測試代碼:
public class QuartzTest {
public static void main(String[] args) throws SchedulerException{
//1.調度器(Scheduler)
SchedulerFactory schedulerfactory = new StdSchedulerFactory();
//拿到調度器,調度器只需要一個即可,可以調度多個任務
Scheduler scheduler = schedulerfactory.getScheduler();
//2.Job實例(JobDetil)
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
.withIdentity("job", "default") //name:任務的名稱,group:分組名
.build();
//3.觸發器(Trigger)
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger", "default") //name:觸發器名稱,group:分組名
.startNow() //馬上執行一次
.withSchedule(CronScheduleBuilder.cronSchedule("0/3 * * * * ?"))//使用Cron觸發器
.build();
//4.讓Job和觸發器關聯
scheduler.scheduleJob(jobDetail,trigger);
scheduler.start();
}
public static class MyJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//打印當前時間
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = dateFormat.format(new Date());
System.out.println(date);
}
}
}
2.執行結果:
cron表達式爲:0/3 * * * * ? 即從0秒開始,每間隔3秒執行一次。
十、StdSchedulerFactory的配置
上文中介紹了StdSchedulerFactory的API,其中就有一個initialize(Properties props)方法,對StdSchedulerFactory進行初始化,常用的配置的屬性名和值如下:
屬性名 | 說明 |
org.quartz.threadPool.class | 使用哪個線程池(要實現org.quartz.spi.ThreadPool接口的線程池),一般用org.quartz.simpl.SimpleThreadPool |
org.quartz.threadPool.threadCount | 線程池線程數量,根據自己情況定,最好不要超過100 |
org.quartz.threadPool.threadPriority | 線程優先級,1-10,數字越小優先級越高,一般用5即可。 |
|
調度器的名字 |
|
爲調度器創建一個Key值,這個Key必須在所有調度器中唯一,一般填寫AUTO,讓quartz自動生成。 |
|
任務調度存儲(需要實現org.quartz.spi.JobStore接口的實例),一般用org.quartz.impl.jdbcjobstore.JobStoreTX |
十一、工具類
上文大致把quartz基本內容概述完畢,下一篇博客將會進行高級內容概述,在此之前,先奉上本人自己寫的一個quartz任務調度工具類,能夠及其方便的根據間隔或corn表達式調度任意一個類的某個方法,代碼如下:
public class SchedulerUtils {
private static StdSchedulerFactory schedulerfactory = new StdSchedulerFactory();
public static final int SECONDS = 1;
public static final int MINUTES = 2;
public static final int HOURS = 3;
private static String CLASS_KEY = "CLASS-KEY";
private static String METHOD_KEY = "METHOD-KEY";
private static String PARAMS_KEY = "PARAMS-KEY";
/**
* 初始化StdSchedulerFactory
* @param map 初始化參數
* @throws SchedulerException
*/
public static void init(Map<String,String> map) throws SchedulerException {
Properties properties = new Properties();
for(Map.Entry<String, String> entry : map.entrySet()) {
properties.setProperty(entry.getKey(),entry.getValue());
}
init(properties);
}
public static void init(Properties properties) throws SchedulerException {
schedulerfactory.initialize(properties);
}
/**
* 按Cron表達式定時執行
* @param clazzName 全類名
* @param methodName 方法名
* @param args 方法參數
* @param cron cron表達式
* @throws Exception
*/
public static void executeJobCron(String clazzName, String methodName, List<Object> args,String cron) throws Exception {
executeJobCron(clazzName,methodName,args,cron,null,null);
}
/**
* 按Cron表達式定時執行
* @param clazzName 全類名
* @param methodName 方法名
* @param args 方法參數
* @param cron cron表達式
* @param startDate 開始時間,如果馬上開始填寫null或 new Date()即可
* @param endDate 結束時間,如果沒有結束時間則填寫null即可
* @throws Exception
*/
public static void executeJobCron(String clazzName, String methodName, List<Object> args,String cron,Date startDate,Date endDate) throws Exception {
JobDetail jobDetail = jobDetailHandle(clazzName, methodName, args);
Trigger trigger = cronTriggerTimeHandle(cron,startDate,endDate);
Scheduler scheduler = getScheduler();
scheduler.scheduleJob(jobDetail,trigger);
scheduler.start();
}
public static void executeJob(String clazzName, String methodName, List<Object> args, int timeUnit, int interval, Date endDate) throws Exception{
executeJob(clazzName,methodName,args,timeUnit,interval,-1,null,endDate);
}
public static void executeJob(String clazzName, String methodName, List<Object> args, int timeUnit, int interval) throws Exception{
executeJob(clazzName,methodName,args,timeUnit,interval,-1,null,null);
}
public static void executeJob(String clazzName, String methodName, List<Object> args, int timeUnit, int interval, int count) throws Exception{
executeJob(clazzName,methodName,args,timeUnit,interval,count,null,null);
}
/**
* 按照間隔時間定時執行
* @param clazzName 全類名
* @param methodName 方法名
* @param args 方法參數
* @param timeUnit 時間單位,參考本類屬性定義
* @param interval 間隔長度
* @param count 執行總數,如果執行總數和結束時間都有,則按結束時間。
* @param startDate 開始時間,如果馬上開始填寫null或 new Date()即可
* @param endDate 結束時間,如果沒有結束時間則填寫null即可
* @throws Exception
*/
public static void executeJob(String clazzName, String methodName, List<Object> args, int timeUnit, int interval, int count,Date startDate,Date endDate) throws Exception {
JobDetail jobDetail = jobDetailHandle(clazzName, methodName, args);
Trigger trigger = simpleTriggerTimeHandle(timeUnit,interval, count,startDate,endDate);
Scheduler scheduler = getScheduler();
scheduler.scheduleJob(jobDetail,trigger);
scheduler.start();
}
private static JobDetail jobDetailHandle(String clazzName, String methodName, List<Object> args) throws NoSuchMethodException, ClassNotFoundException {
JobDataMap jobDataMap = new JobDataMap();
Class clazz = Class.forName(clazzName);
Method method = findMethod(clazz,methodName,args);
jobDataMap.put(CLASS_KEY,clazz);
jobDataMap.put(METHOD_KEY,method);
jobDataMap.put(PARAMS_KEY,args);
JobDetail jobDetail = JobBuilder.newJob(TaskJob.class)
.withIdentity("job")
.usingJobData(jobDataMap)
.build();
return jobDetail;
}
private static Trigger simpleTriggerTimeHandle(int timeUnit, int interval, int count, Date startDate,Date emdDate) {
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger()
.withIdentity("simpleTrigger");
if(startDate == null) {
startDate = new Date();
}
triggerBuilder.startAt(startDate);
triggerBuilder.endAt(emdDate);
if(count > 0) {
switch (timeUnit) {
case SECONDS : triggerBuilder.withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(count,interval));
break;
case MINUTES : triggerBuilder.withSchedule(SimpleScheduleBuilder.repeatMinutelyForTotalCount(count,interval));
break;
case HOURS : triggerBuilder.withSchedule(SimpleScheduleBuilder.repeatHourlyForTotalCount(count,interval));
break;
}
}
return triggerBuilder.build();
}
private static Trigger cronTriggerTimeHandle(String cron,Date startDate,Date emdDate) throws ParseException {
new CronExpression(cron);
if(startDate == null) {
startDate = new Date();
}
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("cronTrigger")
.startAt(startDate)
.endAt(emdDate)
.withSchedule(CronScheduleBuilder.cronSchedule(cron))
.build();
return trigger;
}
private static Scheduler getScheduler() throws SchedulerException {
return schedulerfactory.getScheduler();
}
private static Method findMethod(Class clazz,String methodName,List<Object> args) throws NoSuchMethodException {
Method method;
if(args != null && !args.isEmpty()) {
Class<?>[] paramsTypes = getMethodParamsType(args);
method = clazz.getDeclaredMethod(methodName,paramsTypes);
}else {
method = clazz.getDeclaredMethod(methodName);
}
return method;
}
private static Class<?>[] getMethodParamsType(List<Object> methodParams) {
Class<?>[] classs = new Class<?>[methodParams.size()];
int index = 0;
for (Object os : methodParams)
{
classs[index] = os.getClass();
index++;
}
return classs;
}
public static class TaskJob implements Job {
private Map<Class,Object> objectMap = new ConcurrentHashMap<Class, Object>();
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
JobDataMap dataMap = jobExecutionContext.getMergedJobDataMap();
Class clazz = (Class) dataMap.get(CLASS_KEY);
Object object;
try {
object = getObject(clazz);
Method method = (Method) dataMap.get(METHOD_KEY);
Parameter[] parameters = method.getParameters();
if (parameters.length > 0) {
List<Object> args = (List<Object>) dataMap.get(PARAMS_KEY);
Object[] objects = args.toArray();
method.invoke(object, objects);
}else {
method.invoke(object);
}
}catch (Exception e) {
e.printStackTrace();
}
}
private Object getObject(Class clazz) throws IllegalAccessException, InstantiationException {
Object object = objectMap.get(clazz);
if(object == null) {
object = clazz.newInstance();
objectMap.put(clazz,object);
}
return object;
}
}
}