下面列出了怎么用org.springframework.core.type.classreading.CachingMetadataReaderFactory的API类实例代码及写法,或者点击链接到github查看源代码。
public static void main(String[] args) throws IOException {
// @TransactionalService 标注在当前类 TransactionalServiceAnnotationMetadataBootstrap
String className = TransactionalServiceAnnotationMetadataBootstrap.class.getName();
// 构建 MetadataReaderFactory 实例
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();
// 读取 @TransactionService MetadataReader 信息
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
// 读取 @TransactionService AnnotationMetadata 信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
annotationMetadata.getAnnotationTypes().forEach(annotationType -> {
Set<String> metaAnnotationTypes = annotationMetadata.getMetaAnnotationTypes(annotationType);
metaAnnotationTypes.forEach(metaAnnotationType -> {
System.out.printf("注解 @%s 元标注 @%s\n", annotationType, metaAnnotationType);
});
});
}
/**
* Let typeAliasesPackage alias bean support wildcards.
*
* @return
*/
private Class<?>[] getTypeAliases(PathMatchingResourcePatternResolver resolver) throws Exception {
List<Class<?>> typeAliases = new ArrayList<>();
// Define metadataReader
MetadataReaderFactory metadataReaderFty = new CachingMetadataReaderFactory(resolver);
for (String pkg : typeAliasesPackage.split(",")) {
// Get location
String location = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(pkg)
+ "**/*.class";
// Get resources.
Resource[] resources = resolver.getResources(location);
if (resources != null) {
for (Resource resource : resources) {
if (resource.isReadable()) {
MetadataReader metadataReader = metadataReaderFty.getMetadataReader(resource);
typeAliases.add(Class.forName(metadataReader.getClassMetadata().getClassName()));
}
}
}
}
return typeAliases.toArray(new Class<?>[] {});
}
private List<Class<?>> findMangoDaoClasses(String packages) {
try {
List<Class<?>> daos = new ArrayList<Class<?>>();
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
for (String locationPattern : getLocationPattern(packages)) {
Resource[] rs = resourcePatternResolver.getResources(locationPattern);
for (Resource r : rs) {
MetadataReader reader = metadataReaderFactory.getMetadataReader(r);
AnnotationMetadata annotationMD = reader.getAnnotationMetadata();
if (annotationMD.hasAnnotation(DB.class.getName())) {
ClassMetadata clazzMD = reader.getClassMetadata();
daos.add(Class.forName(clazzMD.getClassName()));
}
}
}
return daos;
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
private void beforeHandlerResource(
ConcurrentHashMap<String, ConcurrentHashMap<HandlerScope, LinkedList<String>>> handlersMap) {
try {
if (!this.packagesList.isEmpty()) {
for (String pkg : this.packagesList) {
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
+ ClassUtils.convertClassNameToResourcePath(pkg)
+ RESOURCE_PATTERN;
Resource[] resources = this.resourcePatternResolver
.getResources(pattern);
MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(
this.resourcePatternResolver);
onHandlerResource(resources, readerFactory, handlersMap);
}
}
} catch (IOException e) {
log.fatal("扫描业务处理异常", e);
}
}
public static List<Class> searchAnnotatedClasses(String basePackage, Class<?> annotation)
throws IOException, ClassNotFoundException {
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(
resourcePatternResolver);
List<Class> candidates = new ArrayList<>();
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + "/" + "**/*.class";
Resource[] resources = resourcePatternResolver.getResources(packageSearchPath);
for (Resource resource : resources) {
if (resource.isReadable()) {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
if (isCandidate(metadataReader, annotation)) {
candidates.add(Class.forName(metadataReader.getClassMetadata().getClassName()));
}
}
}
return candidates;
}
/**
* Finds all the classes which have a BeanTag or BeanTags annotation
*
* @param basePackage the package to start in
* @return classes which have BeanTag or BeanTags annotation
* @throws IOException
* @throws ClassNotFoundException
*/
protected static List<Class<?>> findTagClasses(String basePackage) throws IOException, ClassNotFoundException {
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
List<Class<?>> classes = new ArrayList<Class<?>>();
String resolvedBasePackage = ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders(
basePackage));
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolvedBasePackage + "/" + "**/*.class";
Resource[] resources = resourcePatternResolver.getResources(packageSearchPath);
for (Resource resource : resources) {
if (resource.isReadable()) {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
if (metadataReader != null && isBeanTag(metadataReader)) {
classes.add(Class.forName(metadataReader.getClassMetadata().getClassName()));
}
}
}
return classes;
}
private List<Class<?>> findMyTypes(String basePackage) throws IOException, ClassNotFoundException {
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
List<Class<?>> candidates = new ArrayList<>();
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage)
+ "/**/*.class";
Resource[] resources = resourcePatternResolver.getResources(packageSearchPath);
for (Resource resource : resources) {
if (resource.isReadable()) {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
if (isCandidate(metadataReader)) {
candidates.add(Class.forName(metadataReader.getClassMetadata().getClassName()));
}
}
}
return candidates;
}
private void resetCachingMetadataReaderFactoryCache() {
if (getMetadataReaderFactory() instanceof CachingMetadataReaderFactory) {
Map metadataReaderCache = (Map) ReflectionHelper.getNoException(getMetadataReaderFactory(),
CachingMetadataReaderFactory.class, "metadataReaderCache");
if (metadataReaderCache == null)
metadataReaderCache = (Map) ReflectionHelper.getNoException(getMetadataReaderFactory(),
CachingMetadataReaderFactory.class, "classReaderCache");
if (metadataReaderCache != null) {
metadataReaderCache.clear();
LOGGER.debug("Cache cleared: CachingMetadataReaderFactory.clearCache()");
} else {
LOGGER.warning("Cache NOT cleared: neither CachingMetadataReaderFactory.metadataReaderCache nor clearCache does not exist.");
}
}
}
private List<Class<?>> findMangoDaoClasses() {
try {
List<Class<?>> daos = new ArrayList<Class<?>>();
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
for (String locationPattern : locationPatterns) {
Resource[] rs = resourcePatternResolver.getResources(locationPattern);
for (Resource r : rs) {
MetadataReader reader = metadataReaderFactory.getMetadataReader(r);
AnnotationMetadata annotationMD = reader.getAnnotationMetadata();
if (annotationMD.hasAnnotation(DB.class.getName())) {
ClassMetadata clazzMD = reader.getClassMetadata();
daos.add(Class.forName(clazzMD.getClassName()));
}
}
}
return daos;
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
/**
* Finds the beans classes that are annotated with {@code CsvReport} and extends the
* {@code Report} base class.
*
* @param basePackage the package to be scanned.
* @return the list of classes that match the requirements to be a report bean.
*/
private List<Class<? extends Report>> findReportBeans(String basePackage) throws IOException,
ClassNotFoundException {
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
MetadataReaderFactory metadataReaderFactory =
new CachingMetadataReaderFactory(resourcePatternResolver);
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
+ resolveBasePackage(basePackage) + "/" + "**/*.class";
Resource[] resources = resourcePatternResolver.getResources(packageSearchPath);
List<Class<? extends Report>> candidates = new ArrayList<Class<? extends Report>>();
for (Resource resource : resources) {
addCandidateIfApplicable(resource, metadataReaderFactory, candidates);
}
return candidates;
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
Assert.notNull(resourceLoader, "ResourceLoader must not be null");
this.resourceLoader = resourceLoader;
if (!this.setMetadataReaderFactoryCalled) {
this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
}
}
@Override
public void setBeanClassLoader(ClassLoader beanClassLoader) {
this.beanClassLoader = beanClassLoader;
if (!this.setMetadataReaderFactoryCalled) {
this.metadataReaderFactory = new CachingMetadataReaderFactory(beanClassLoader);
}
}
/**
* Return the MetadataReaderFactory used by this component provider.
*/
public final MetadataReaderFactory getMetadataReaderFactory() {
if (this.metadataReaderFactory == null) {
this.metadataReaderFactory = new CachingMetadataReaderFactory();
}
return this.metadataReaderFactory;
}
/**
* Clear the local metadata cache, if any, removing all cached class metadata.
*/
public void clearCache() {
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
@Override
protected ConfigurationClassParser newParser() {
return new ConfigurationClassParser(
new CachingMetadataReaderFactory(),
new FailFastProblemReporter(),
new StandardEnvironment(),
new DefaultResourceLoader(),
new AnnotationBeanNameGenerator(),
new DefaultListableBeanFactory());
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
Assert.notNull(resourceLoader, "ResourceLoader must not be null");
this.resourceLoader = resourceLoader;
if (!this.setMetadataReaderFactoryCalled) {
this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
}
}
@Override
public void setBeanClassLoader(ClassLoader beanClassLoader) {
this.beanClassLoader = beanClassLoader;
if (!this.setMetadataReaderFactoryCalled) {
this.metadataReaderFactory = new CachingMetadataReaderFactory(beanClassLoader);
}
}
/**
* Return the MetadataReaderFactory used by this component provider.
*/
public final MetadataReaderFactory getMetadataReaderFactory() {
if (this.metadataReaderFactory == null) {
this.metadataReaderFactory = new CachingMetadataReaderFactory();
}
return this.metadataReaderFactory;
}
/**
* Clear the local metadata cache, if any, removing all cached class metadata.
*/
public void clearCache() {
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
@Override
protected ConfigurationClassParser newParser() {
return new ConfigurationClassParser(
new CachingMetadataReaderFactory(),
new FailFastProblemReporter(),
new StandardEnvironment(),
new DefaultResourceLoader(),
new AnnotationBeanNameGenerator(),
new DefaultListableBeanFactory());
}
@Override
public void setTypeAliasesPackage(String typeAliasesPackage) {
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
typeAliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
ClassUtils.convertClassNameToResourcePath(typeAliasesPackage) + "/" + DEFAULT_RESOURCE_PATTERN;
//将加载多个绝对匹配的所有Resource
//将首先通过ClassLoader.getResource("META-INF")加载非模式路径部分
//然后进行遍历模式匹配
try {
List<String> result = new ArrayList<>();
Resource[] resources = resolver.getResources(typeAliasesPackage);
if (resources.length > 0) {
MetadataReader metadataReader = null;
for (Resource resource : resources) {
if (resource.isReadable()) {
metadataReader = metadataReaderFactory.getMetadataReader(resource);
result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
}
}
}
if (!result.isEmpty()) {
super.setTypeAliasesPackage(StringUtils.join(result.toArray(), ","));
} else {
String msg = String.format("参数typeAliasesPackage:%s,未找到任何包", typeAliasesPackage);
logger.warn(msg);
}
} catch (IOException | ClassNotFoundException e) {
logger.info(e.getMessage());
}
}
public SimpleConditionService(BeanDefinitionRegistry registry, ConfigurableListableBeanFactory beanFactory,
Environment environment, ResourceLoader resourceLoader) {
this.beanFactory = beanFactory;
this.evaluator = new ConditionEvaluator(registry, environment, resourceLoader);
this.classLoader = resourceLoader.getClassLoader();
String metadataFactory = MetadataReaderFactory.class.getName();
this.metadataReaderFactory = beanFactory.containsSingleton(metadataFactory)
? (MetadataReaderFactory) beanFactory.getSingleton(metadataFactory)
: new CachingMetadataReaderFactory(this.classLoader);
}
private ConditionService initialize(GenericApplicationContext context) {
if (!context.getBeanFactory().containsSingleton(ConditionService.class.getName())) {
if (!context.getBeanFactory().containsSingleton(MetadataReaderFactory.class.getName())) {
context.getBeanFactory().registerSingleton(MetadataReaderFactory.class.getName(),
new CachingMetadataReaderFactory(context.getClassLoader()));
}
context.getBeanFactory().registerSingleton(ConditionService.class.getName(),
new SimpleConditionService(context, context.getBeanFactory(), context.getEnvironment(), context));
context.registerBean(ImportRegistrars.class, () -> new FunctionalInstallerImportRegistrars(context));
}
return (ConditionService) context.getBeanFactory().getSingleton(ConditionService.class.getName());
}
public FunctionalInstallerImportRegistrars(GenericApplicationContext context) {
this.context = context;
String metadataFactory = MetadataReaderFactory.class.getName();
this.metadataReaderFactory = context.getBeanFactory().containsSingleton(metadataFactory)
? (MetadataReaderFactory) context.getBeanFactory().getSingleton(metadataFactory)
: new CachingMetadataReaderFactory(context.getClassLoader());
}
@Override
public void initialize(GenericApplicationContext context) {
if (!ClassUtils.isPresent("org.springframework.boot.test.context.ImportsContextCustomizer",
context.getClassLoader())
|| !context.getEnvironment().getProperty("spring.functional.enabled", Boolean.class, true)) {
// Only used in tests - could move to separate jar
return;
}
ImportRegistrars registrars;
// TODO: extract this logic and share with FunctionalInstallerListener?
if (!context.getBeanFactory().containsSingleton(ConditionService.class.getName())) {
if (!context.getBeanFactory().containsSingleton(MetadataReaderFactory.class.getName())) {
context.getBeanFactory().registerSingleton(MetadataReaderFactory.class.getName(),
new CachingMetadataReaderFactory(context.getClassLoader()));
}
context.getBeanFactory().registerSingleton(ConditionService.class.getName(),
new SimpleConditionService(context, context.getBeanFactory(), context.getEnvironment(), context));
registrars = new FunctionalInstallerImportRegistrars(context);
context.registerBean(ImportRegistrars.class, () -> registrars);
}
else {
registrars = context.getBean(ImportRegistrars.class.getName(), ImportRegistrars.class);
}
for (String name : context.getBeanFactory().getBeanDefinitionNames()) {
BeanDefinition definition = context.getBeanFactory().getBeanDefinition(name);
if (definition.getBeanClassName().contains("ImportsContextCustomizer$ImportsConfiguration")) {
SimpleConditionService.EXCLUDES_ENABLED = true;
Class<?> testClass = (definition != null) ? (Class<?>) definition.getAttribute("testClass") : null;
if (testClass != null) {
Set<Import> merged = AnnotatedElementUtils.findAllMergedAnnotations(testClass, Import.class);
for (Import ann : merged) {
for (Class<?> imported : ann.value()) {
registrars.add(testClass, imported);
}
}
}
}
}
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
Assert.notNull(resourceLoader, "ResourceLoader must not be null");
this.resourceLoader = resourceLoader;
if (!this.setMetadataReaderFactoryCalled) {
this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
}
}
@Override
public void setBeanClassLoader(ClassLoader beanClassLoader) {
this.beanClassLoader = beanClassLoader;
if (!this.setMetadataReaderFactoryCalled) {
this.metadataReaderFactory = new CachingMetadataReaderFactory(beanClassLoader);
}
}
@Override
public void setBeanClassLoader(ClassLoader beanClassLoader) {
this.beanClassLoader = beanClassLoader;
if (!this.setMetadataReaderFactoryCalled) {
this.metadataReaderFactory = new CachingMetadataReaderFactory(beanClassLoader);
}
}
@Override
protected ConfigurationClassParser newParser() {
return new ConfigurationClassParser(
new CachingMetadataReaderFactory(),
new FailFastProblemReporter(),
new StandardEnvironment(),
new DefaultResourceLoader(),
new AnnotationBeanNameGenerator(),
new DefaultListableBeanFactory());
}
private void scanAndRegisterAnnotationTopics(String[] scanBasePackages){
String RESOURCE_PATTERN = "/**/*.class";
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
for (String scanBasePackage : scanBasePackages) {
logger.info(">>begin scan package [{}] with Annotation[ConsumerHandler] MessageHanlder ",scanBasePackage);
try {
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(scanBasePackage)
+ RESOURCE_PATTERN;
org.springframework.core.io.Resource[] resources = resourcePatternResolver.getResources(pattern);
MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
for (org.springframework.core.io.Resource resource : resources) {
if (resource.isReadable()) {
MetadataReader reader = readerFactory.getMetadataReader(resource);
String className = reader.getClassMetadata().getClassName();
Class<?> clazz = Class.forName(className);
if(clazz.isAnnotationPresent(ConsumerHandler.class)){
ConsumerHandler annotation = clazz.getAnnotation(ConsumerHandler.class);
MessageHandler hander = (MessageHandler) context.getBean(clazz);
if(!topicHandlers.containsKey(annotation.topic())){
topicHandlers.put(annotation.topic(), hander);
logger.info("register new MessageHandler:{}-{}",annotation.topic(),clazz.getName());
}
}
}
}
logger.info("<<scan package["+scanBasePackage+"] finished!");
} catch (Exception e) {
if(e instanceof org.springframework.beans.factory.NoSuchBeanDefinitionException){
throw (org.springframework.beans.factory.NoSuchBeanDefinitionException)e;
}
logger.error("<<scan package["+scanBasePackage+"] error", e);
}
}
}