1. 程式人生 > >Java Scala獲取註解的類信息

Java Scala獲取註解的類信息

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獲取註解的類信息