Java Scala获取注解的类信息 Quartz实现分布式可动态配置的定时任务

要想获取使用指定注解的类信息,可借助工具:

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实现可配置的分布式定时任务的优化重构,可详见:

Quartz实现分布式可动态配置的定时任务

猜你喜欢

转载自www.cnblogs.com/barrywxx/p/10810055.html