版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_30038111/article/details/82703383
ClassPathScanningCandidateComponentProvider
是Spring
提供的工具,可以按自定义的类型,查找classpath
下符合要求的class文件。
public static void main(String[] args) throws ClassNotFoundException {
// true:默认TypeFilter生效,这种模式会查询出许多不符合你要求的class名
// false:关闭默认TypeFilter
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(
false);
// 扫描带有自定义注解的类
provider.addIncludeFilter(new AnnotationTypeFilter(ScanAnnotation.class));
// 接口不会被扫描,其子类会被扫描出来
provider.addIncludeFilter(new AssignableTypeFilter(ScanClassInterface.class));
// Spring会将 .换成/ ("."-based package path to a "/"-based)
// Spring拼接的扫描地址:classpath*:xxx/xxx/xxx/**/*.class
// Set<BeanDefinition> scanList = provider.findCandidateComponents("com.p7.demo.scanclass");
Set<BeanDefinition> scanList = provider.findCandidateComponents("*");
for (BeanDefinition beanDefinition : scanList) {
System.out.println(beanDefinition.getBeanClassName());
}
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ScanAnnotation {
}
public interface ScanClassInterface {
}
public class AClass implements ScanClassInterface {
}
@ScanAnnotation
public class CClass {
}
案例
多个系统都使用到org.quartz
定时任务,为了解决业务问题,每个系统中的需要的业务参数肯定不同,并且要提供随时可以添加定时任务的功能。在一些公司,针对多个系统,都会开发一套运维管理平台,管理系统中的数据,或协调系统资源,或协助实施人员临时解决线上问题等,运维管理平台可以仅供公司内部人员使用,或者提供给受过培训的人员使用。
那么针对这个定时任务的需求,也可以将功能添加到运维管理平台上,并且针对业务类型的不同或者业务复杂程度的不同,Job
类型的多样性要求我们封装自己的Job
实体。此时问题就来了,使用运维管理平台创建定时任务时,首先我们知道应该在哪个系统上创建,第二应该创建哪个类型的Job
。
针对第二个问题的实现,我们可以预定义一些key/value
进行转换,例如前端传递的“通用任务”字符串对应com.xxx.xxx.CommonJob
类,这种要额外维护key/value
;或者是直接暴露要操作的系统中所有的类全限定名的列表,由前端传入任务类的全限定名,在后端进行处理,这种就可以使用ClassPathScanningCandidateComponentProvider
去扫描类的权限定名。(一般情况下,运维管理平台是公司内部使用,不用担心安全性问题)
Class<? extends Job> jobClazz = (Class<? extends Job>) Class.forName(StringUtils.trim(clazzStr));
// 创建任务明细
JobDetail jobDetail = JobBuilder.newJob(jobClazz )
// 任务执行类
.withIdentity(jobName, jobGroupName)
.setJobData(jobDataMap)
.withDescription(description)
// 任务名,任务组
.build();