package com.wechat.util;
import com.wechat.exception.WeChatException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.AssignableTypeFilter;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
/**
* 类扫描器
*
* @author 80123389
*/
@Slf4j
public class ClassScanner {
/**
* 扫描指定包下所有类
*
* @param packagePath 包路径
* @param assignableType 要扫描的类类型
* @return 类集合
*/
public static Set<Class<?>> scanClasses(String packagePath, Class assignableType) {
Set<Class<?>> classes = new HashSet<>();
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new AssignableTypeFilter(assignableType));
for (BeanDefinition beanDefinition : provider.findCandidateComponents(packagePath)) {
String className = beanDefinition.getBeanClassName();
try {
classes.add(Class.forName(className));
} catch (ClassNotFoundException e) {
log.info("类扫描失败:{}", className, e);
}
}
return classes;
}
/**
* 扫描指定包下所有带有指定注解的类
*
* @param packagePath 包路径
* @param annotationClass 注解类
* @return 类集合
*/
public static Set<Class<?>> scanClassesWithAnnotation(String packagePath, Class<? extends Annotation> annotationClass) {
Set<Class<?>> classes = new HashSet<>();
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false) {
@Override
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
MetadataReader metadataReader = null;
try {
metadataReader = getMetadataReaderFactory().getMetadataReader(Objects.requireNonNull(beanDefinition.getBeanClassName()));
} catch (IOException e) {
throw new WeChatException("类扫描失败", true);
}
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
Set<String> annotationTypes = metadata.getAnnotationTypes();
for (String annotationType : annotationTypes) {
if (annotationClass.getName().equals(annotationType)) {
return true; // 标记为候选组件
}
}
return false;
}
};
provider.addIncludeFilter(new AnnotationTypeFilter(annotationClass));
for (BeanDefinition beanDefinition : provider.findCandidateComponents(packagePath)) {
String className = beanDefinition.getBeanClassName();
try {
classes.add(Class.forName(className));
} catch (ClassNotFoundException e) {
log.info("类扫描失败:{}", className);
}
}
return classes;
}
}
package com.wechat;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.bind.annotation.PostMapping;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* @ClassName SpringBootTest01
* @Description
* @Author xuxiang
* @Date 11:17 2022/11/8
**/
@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class SpringBootTest03 {
@Test
public void test01() throws Exception {
Set<Class<?>> classesInPackage = ClassScanner.scanClassesWithAnnotation("com.wechat.api", Api.class);
System.out.println(JSONUtil.toJsonStr(classesInPackage));
}
}