Java Scala獲取註解的類信息
阿新 • • 發佈:2019-05-05
lang 成員變量 1.0 全局 statement 枚舉 ask time style
要想獲取使用指定註解的類信息,可借助工具:
org.reflections.Reflections
此工具將Java反射進行了高級封裝,Reflections 通過掃描 classpath,索引元數據,允許在運行時查詢這些元數據,也可以保存收集項目中多個模塊的元數據信息。
使用 Reflections 可以查詢以下元數據信息:
1)獲得某個類型的所有子類型 2)獲得標記了某個註解的所有類型/成員變量,支持註解參數匹配。 3)使用正則表達式獲得所有匹配的資源文件 4)獲得所有特定簽名(包括參數,參數註解,返回值)的方法
Reflections 依賴 Google 的 Guava 庫和 Javassist 庫。
Maven引入方式:
<dependency> <groupId>org.reflections</groupId> <artifactId>reflections</artifactId> <version>0.9.11</version> </dependency>
sbt引入方式:
"org.reflections" % "reflections" % "0.9.11"
首先自定義註解:
package com.today.service.financetask.job
import java.lang.annotation.*; /** * 類功能描述:job 信息註解 * * @author WangXueXing create at 19-5-4 上午9:14 * @version 1.0.0 */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface JobInfo { /** * job id * @return */ String jobId();/** * job name * @return */ String jobName(); /** * default cron * @return */ String defaultCron(); }
將某些類添加註解:
package com.today.service.financetask.job
import java.util.Calendar import com.today.api.checkaccount.scala.CheckAccountServiceClient import com.today.api.checkaccount.scala.enums.FlatFormTypeEnum import com.today.api.checkaccount.scala.request.ReconciliationRequest import com.today.service.financetask.job.define.AbstractJob import com.today.service.financetask.utils.JobInfo import org.quartz.JobExecutionContext /** * 自動對賬 */ @JobInfo(jobId="CHECK_ACCOUNT_PROCESS", jobName="對賬系統自動對賬定時任務", defaultCron="0 0 13 * * ?") class CheckAccountJob extends AbstractJob{ /** * start up the scheduled task * * @param context JobExecutionContext */ override def run(context: JobExecutionContext): Unit = { val cal = Calendar.getInstance cal.add(Calendar.DATE, -1) new CheckAccountServiceClient().appReconciliation(new ReconciliationRequest(FlatFormTypeEnum.TODAY_APP,None)) } }
import com.today.service.financetask.action.DailyStatementAction import com.today.service.financetask.job.define.AbstractJob import com.today.service.financetask.utils.JobInfo import org.quartz.JobExecutionContext import org.springframework.stereotype.Service /** * 日次處理定時任務處理 * * @author zhangc create at 2018/5/11 14:08 * @version 0.0.1 */ @Service @JobInfo(jobId="DAY_TIME_PROCESS", jobName="日次處理定時任務", defaultCron="0 30 2 * * ?") class DayTimeProcessJob extends AbstractJob{ /** * start up the scheduled task * * @param context JobExecutionContext */ override def run(context: JobExecutionContext): Unit = { new DailyStatementAction().execute } }
通過Java反射及Reflections工具類實現被JobInfo註解的所有類信息:
import java.util import com.today.service.financetask.utils.JobInfo import org.quartz.Job import org.reflections.Reflections import scala.collection.JavaConverters._ import scala.collection.mutable /** * 通過註解獲取所有通用Job信息 * * @author BarryWang create at 2018/5/12 10:45 * @version 0.0.1 */ object JobEnum { /** * 獲取添加JobInfo註解的類信息 */ val jobWithAnnotation: util.Set[Class[_]] = new Reflections("com.today.service.financetask.job").getTypesAnnotatedWith(classOf[JobInfo]) /** * 獲取所有job枚舉值 * @return */ def values : mutable.Set[JobInfo] = jobWithAnnotation.asScala.map(getJobInfo(_)) /** * 根據job class 獲取job 信息 * @param jobClass * @return */ def getJobInfo(jobClass : Class[_]): JobInfo = jobClass.getAnnotation(classOf[JobInfo]) /** * jobId與jobName映射關系 * @return */ def jobIdNameMap : Map[String, String]={ jobWithAnnotation.asScala.map{sub => val jobInfo = getJobInfo(sub) Map(jobInfo.jobId() -> jobInfo.jobName()) }.fold(Map())((i,j) => i++j) } /** * JobObject與JobEnum映射關系 * @return */ def jobClassInfoMap: Map[String, JobInfo] = { jobWithAnnotation.asScala.map{sub => Map(sub.getName -> getJobInfo(sub)) }.fold(Map())((i,j) => i++j) } /** * jobId與JobEnum映射關系 * @return */ def jobIdInfoMap: Map[String, JobInfo] = { jobWithAnnotation.asScala.map{sub => val jobInfo = getJobInfo(sub) Map(jobInfo.jobId() -> jobInfo) }.fold(Map())((i,j) => i++j) } /** * jobId與JobObject映射關系 * @return */ def jobIdClassMap: Map[String, Class[_ <: Job]] = { jobWithAnnotation.asScala.map{sub => Map(getJobInfo(sub).jobId() -> sub.asInstanceOf[Class[_ <: Job]]) }.fold(Map[String, Class[_ <: Job]]())((i,j) => i++j) } def main(args: Array[String]): Unit = { println(jobIdClassMap) } }
至此,我們就可以獲取所有被特定註解引用的類信息及註解信息,我們就可以全局管理特定類信息。
本部分也是對Quartz實現可配置的分布式定時任務的優化重構,可詳見:
Java Scala獲取註解的類信息