下面列出了怎么用org.springframework.core.type.classreading.MetadataReader的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
SimpleMetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory(applicationContext);
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) beanFactory;
String resolvedPath = resolvePackageToScan();
logger.debug("Scanning '{}' for JSON-RPC service interfaces.", resolvedPath);
try {
for (Resource resource : applicationContext.getResources(resolvedPath)) {
if (resource.isReadable()) {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
ClassMetadata classMetadata = metadataReader.getClassMetadata();
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
String jsonRpcPathAnnotation = JsonRpcService.class.getName();
if (annotationMetadata.isAnnotated(jsonRpcPathAnnotation)) {
String className = classMetadata.getClassName();
String path = (String) annotationMetadata.getAnnotationAttributes(jsonRpcPathAnnotation).get("value");
logger.debug("Found JSON-RPC service to proxy [{}] on path '{}'.", className, path);
registerJsonProxyBean(defaultListableBeanFactory, className, path);
}
}
}
} catch (IOException e) {
throw new IllegalStateException(format("Cannot scan package '%s' for classes.", resolvedPath), e);
}
}
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);
}
}
OrderedAnnotatedElement(MetadataReaderFactory metadataReaderFactory, String name)
throws IOException {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(name);
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
Map<String, Object> attributes = metadata
.getAnnotationAttributes(Order.class.getName());
this.name = name;
if (attributes != null && attributes.containsKey("value")) {
this.value = (Integer) attributes.get("value");
this.order = new Order() {
@Override
public Class<? extends Annotation> annotationType() {
return Order.class;
}
@Override
public int value() {
return OrderedAnnotatedElement.this.value;
}
};
}
}
public Set<Class<?>> doScan(String basePackage) {
Set<Class<?>> classes = new HashSet<Class<?>>();
try {
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + org.springframework.util.ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders(basePackage)) + "/**/*.class";
Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
for (int i = 0; i < resources.length; i++) {
Resource resource = resources[i];
if (resource.isReadable()) {
MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
if ((includeFilters.size() == 0 && excludeFilters.size() == 0) || matches(metadataReader)) {
try {
classes.add(Class.forName(metadataReader.getClassMetadata().getClassName()));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
} catch (IOException ex) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
}
return classes;
}
/**
* 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;
}
/**
* Returns true if the metadataReader representing the class has a BeanTag or BeanTags annotation
*
* @param metadataReader MetadataReader representing the class to analyze
* @return true if BeanTag or BeanTags annotation is present
*/
protected static boolean isBeanTag(MetadataReader metadataReader) {
try {
Class<?> c = Class.forName(metadataReader.getClassMetadata().getClassName());
if (c.getAnnotation(BeanTag.class) != null || c.getAnnotation(BeanTags.class) != null) {
return true;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return false;
}
@Override
public boolean match(MetadataReader metadataReader,
MetadataReaderFactory metadataReaderFactory) throws IOException {
for (TypeFilter filter : this.delegates) {
if (!filter.match(metadataReader, metadataReaderFactory)) {
return false;
}
}
return true;
}
@Test
public void asmAnnotationMetadataForSubclass() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(AnnotatedComponentSubClass.class.getName());
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
doTestSubClassAnnotationInfo(metadata);
}
public Class<?> loadClass() throws ClassNotFoundException {
if (this.source instanceof Class) {
return (Class<?>) this.source;
}
String className = ((MetadataReader) this.source).getClassMetadata().getClassName();
return resourceLoader.getClassLoader().loadClass(className);
}
protected MetadataReader loadClassMetadata(String className) {
Resource resource = getResourceLoader().getResource("/" + className.replace(".", "/") + ".class");
if (!resource.isReadable()) {
throw new RuntimeException(String.format("Resource %s is not readable for class %s", resource, className));
}
try {
return getMetadataReaderFactory().getMetadataReader(resource);
} catch (IOException e) {
throw new RuntimeException("Unable to read resource " + resource, e);
}
}
/**
* Determine whether the given class is a candidate component based on any
* {@code @Conditional} annotations.
* @param metadataReader the ASM ClassReader for the class
* @return whether the class qualifies as a candidate component
*/
private boolean isConditionMatch(MetadataReader metadataReader) {
if (this.conditionEvaluator == null) {
this.conditionEvaluator =
new ConditionEvaluator(getRegistry(), this.environment, this.resourcePatternResolver);
}
return !this.conditionEvaluator.shouldSkip(metadataReader.getAnnotationMetadata());
}
/**
* Check whether any of the configured entity type filters matches
* the current class descriptor contained in the metadata reader.
*/
private boolean matchesEntityTypeFilter(MetadataReader reader, MetadataReaderFactory readerFactory) throws IOException {
if (this.entityTypeFilters != null) {
for (TypeFilter filter : this.entityTypeFilters) {
if (filter.match(reader, readerFactory)) {
return true;
}
}
}
return false;
}
/**
* @return True if the given MetadataReader shows that the class is
* annotated by <code>javax.persistence.Enity</code>
*/
private boolean isEntityClass(MetadataReader metadataReader) {
Set<String> annTypes = metadataReader.getAnnotationMetadata()
.getAnnotationTypes();
if (CollectionUtils.isEmpty(annTypes)) {
return false;
}
return annTypes.contains(Entity.class.getName());
}
@Test
public void testSignificantLoad() throws Exception {
Assume.group(TestGroup.LONG_RUNNING);
// the biggest public class in the JDK (>60k)
URL url = getClass().getResource("/java/awt/Component.class");
assertThat(url, notNullValue());
// look at a LOT of items
for (int i = 0; i < ITEMS_TO_LOAD; i++) {
Resource resource = new UrlResource(url) {
@Override
public boolean equals(Object obj) {
return (obj == this);
}
@Override
public int hashCode() {
return System.identityHashCode(this);
}
};
MetadataReader reader = mrf.getMetadataReader(resource);
assertThat(reader, notNullValue());
}
// useful for profiling to take snapshots
// System.in.read();
}
@Test
public void metaAnnotationOverridesUsingAnnotationMetadataReadingVisitor() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(ComposedConfigurationWithAttributeOverridesClass.class.getName());
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
assertMetaAnnotationOverrides(metadata);
}
/**
* Check whether any of the configured entity type filters matches
* the current class descriptor contained in the metadata reader.
*/
private boolean matchesEntityTypeFilter(MetadataReader reader, MetadataReaderFactory readerFactory) throws IOException {
if (this.entityTypeFilters != null) {
for (TypeFilter filter : this.entityTypeFilters) {
if (filter.match(reader, readerFactory)) {
return true;
}
}
}
return false;
}
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) {
// 获取当前正在扫描的类的注解信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
// 获取当前正在扫描的类的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
// 获取当前正在扫描的类的路径等信息
Resource resource = metadataReader.getResource();
String className = classMetadata.getClassName();
return StringUtils.hasText("er");
}
@Test
public void testInheritedAnnotationFromInterfaceDoesNotMatch() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
String classUnderTest = "org.springframework.core.type.AnnotationTypeFilterTests$SomeClassWithSomeComponentInterface";
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(classUnderTest);
AnnotationTypeFilter filter = new AnnotationTypeFilter(InheritedAnnotation.class);
// Must fail as annotation on interfaces should not be considered a match
assertFalse(filter.match(metadataReader, metadataReaderFactory));
ClassloadingAssertions.assertClassNotLoaded(classUnderTest);
}
@Test
public void testNonAnnotatedClassDoesntMatch() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
String classUnderTest = "org.springframework.core.type.AnnotationTypeFilterTests$SomeNonCandidateClass";
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(classUnderTest);
AnnotationTypeFilter filter = new AnnotationTypeFilter(Component.class);
assertFalse(filter.match(metadataReader, metadataReaderFactory));
ClassloadingAssertions.assertClassNotLoaded(classUnderTest);
}
@Test
public void testMatchesInterfacesIfConfigured() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
String classUnderTest = "org.springframework.core.type.AnnotationTypeFilterTests$SomeClassWithSomeComponentInterface";
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(classUnderTest);
AnnotationTypeFilter filter = new AnnotationTypeFilter(InheritedAnnotation.class, false, true);
assertTrue(filter.match(metadataReader, metadataReaderFactory));
ClassloadingAssertions.assertClassNotLoaded(classUnderTest);
}
@Test
public void asmAnnotationMetadata() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(AnnotatedComponent.class.getName());
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
doTestAnnotationInfo(metadata);
doTestMethodAnnotationInfo(metadata);
}
@Test
public void testNonInheritedAnnotationDoesNotMatch() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
String classUnderTest = "org.springframework.core.type.AnnotationTypeFilterTests$SomeSubclassOfSomeClassMarkedWithNonInheritedAnnotation";
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(classUnderTest);
AnnotationTypeFilter filter = new AnnotationTypeFilter(NonInheritedAnnotation.class);
// Must fail as annotation isn't inherited
assertFalse(filter.match(metadataReader, metadataReaderFactory));
ClassloadingAssertions.assertClassNotLoaded(classUnderTest);
}
@Test
public void asmAnnotationMetadataForInterface() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(AnnotationMetadata.class.getName());
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
doTestMetadataForInterfaceClass(metadata);
}
@Test
public void superClassMatch() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
String classUnderTest = "org.springframework.core.type.AssignableTypeFilterTests$SomeDaoLikeImpl";
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(classUnderTest);
AssignableTypeFilter filter = new AssignableTypeFilter(SimpleJdbcDaoSupport.class);
assertTrue(filter.match(metadataReader, metadataReaderFactory));
ClassloadingAssertions.assertClassNotLoaded(classUnderTest);
}
/**
* Check whether any of the configured entity type filters matches
* the current class descriptor contained in the metadata reader.
*/
private boolean matchesEntityTypeFilter(MetadataReader reader, MetadataReaderFactory readerFactory) throws IOException {
if (this.entityTypeFilters != null) {
for (TypeFilter filter : this.entityTypeFilters) {
if (filter.match(reader, readerFactory)) {
return true;
}
}
}
return false;
}
@Test // SPR-11649
public void multipleAnnotationsWithIdenticalAttributeNamesUsingAnnotationMetadataReadingVisitor() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(NamedAnnotationsClass.class.getName());
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
assertMultipleAnnotationsWithIdenticalAttributeNames(metadata);
}
@Test // SPR-11649
public void composedAnnotationWithMetaAnnotationsWithIdenticalAttributeNamesUsingAnnotationMetadataReadingVisitor() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(NamedComposedAnnotationClass.class.getName());
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
assertMultipleAnnotationsWithIdenticalAttributeNames(metadata);
}
@SuppressWarnings("all")
public static void register(String[] packages) {
if (typeHandlerRegistry == null) {
log.error("请在spring容器初始化后再调用此方法!");
return;
}
for (String basePackage : packages) {
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
ClassUtils.convertClassNameToResourcePath(basePackage) + "/**/*.class";
try {
Resource[] resources = resourcePatternResolver.getResources(packageSearchPath);
for (Resource resource : resources) {
try {
MetadataReader reader = metadataReaderFactory.getMetadataReader(resource);
Class enumType = Class.forName(reader.getClassMetadata().getClassName());
if (enumType.isEnum() && EnumDict.class.isAssignableFrom(enumType)) {
log.debug("register enum dict:{}", enumType);
DefaultDictDefineRepository.registerDefine(DefaultDictDefineRepository.parseEnumDict(enumType));
//注册枚举类型
typeHandlerRegistry.register(enumType, new EnumDictHandler(enumType));
//注册枚举数组类型
typeHandlerRegistry.register(Array.newInstance(enumType, 0).getClass(), new EnumDictArrayHandler(enumType));
}
} catch (Exception | Error ignore) {
}
}
} catch (IOException e) {
log.warn("register enum dict error", e);
}
}
}
protected String getControllerId(MetadataReader metadataReader) {
Map<String, Object> uiControllerAnn =
metadataReader.getAnnotationMetadata().getAnnotationAttributes(UiController.class.getName());
String idAttr = null;
String valueAttr = null;
if (uiControllerAnn != null) {
idAttr = (String) uiControllerAnn.get(UiController.ID_ATTRIBUTE);
valueAttr = (String) uiControllerAnn.get(UiController.VALUE_ATTRIBUTE);
}
String className = metadataReader.getClassMetadata().getClassName();
return UiDescriptorUtils.getInferredScreenId(idAttr, valueAttr, className);
}
private String[] getResources(String packageName) {
try {
// 搜索资源
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders(packageName)) + "/" + DEFAULT_RESOURCE_PATTERN;
Resource[] resources = resourcePatternResolver.getResources(packageSearchPath);
// 提取资源
Set<String> names = new HashSet<String>();
String name = CacheConfiguration.class.getName();
for (Resource resource : resources) {
if (!resource.isReadable()) {
continue;
}
// 判断是否静态资源
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
if (!annotationMetadata.hasAnnotation(name)) {
continue;
}
ClassMetadata classMetadata = metadataReader.getClassMetadata();
names.add(classMetadata.getClassName());
}
return names.toArray(new String[0]);
} catch (IOException exception) {
String message = "无法获取资源";
LOGGER.error(message, exception);
throw new CacheConfigurationException(message, exception);
}
}