下面列出了org.springframework.core.type.classreading.MetadataReaderFactory#getMetadataReader ( ) 实例代码,或者点击链接到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);
});
});
}
@Test
public void customRequestScopeViaAsm() throws IOException {
MetadataReaderFactory readerFactory = new SimpleMetadataReaderFactory();
MetadataReader reader = readerFactory.getMetadataReader(AnnotatedWithCustomRequestScope.class.getName());
AnnotatedBeanDefinition bd = new AnnotatedGenericBeanDefinition(reader.getAnnotationMetadata());
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(bd);
assertNotNull("resolveScopeMetadata(..) must *never* return null.", scopeMetadata);
assertEquals("request", scopeMetadata.getScopeName());
assertEquals(NO, scopeMetadata.getScopedProxyMode());
}
@Test
public void testDirectAnnotationMatch() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
String classUnderTest = "org.springframework.core.type.AnnotationTypeFilterTests$SomeComponent";
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(classUnderTest);
AnnotationTypeFilter filter = new AnnotationTypeFilter(InheritedAnnotation.class);
assertTrue(filter.match(metadataReader, metadataReaderFactory));
ClassloadingAssertions.assertClassNotLoaded(classUnderTest);
}
@Test
public void metaAnnotationOverridesUsingAnnotationMetadataReadingVisitor() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(ComposedConfigurationWithAttributeOverridesClass.class.getName());
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
assertMetaAnnotationOverrides(metadata);
}
@Test
public void testInheritedAnnotationFromBaseClassDoesMatch() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
String classUnderTest = "org.springframework.core.type.AnnotationTypeFilterTests$SomeSubclassOfSomeComponent";
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(classUnderTest);
AnnotationTypeFilter filter = new AnnotationTypeFilter(InheritedAnnotation.class);
assertTrue(filter.match(metadataReader, metadataReaderFactory));
ClassloadingAssertions.assertClassNotLoaded(classUnderTest);
}
@Test
public void customRequestScopeViaAsm() throws IOException {
MetadataReaderFactory readerFactory = new SimpleMetadataReaderFactory();
MetadataReader reader = readerFactory.getMetadataReader(AnnotatedWithCustomRequestScope.class.getName());
AnnotatedBeanDefinition bd = new AnnotatedGenericBeanDefinition(reader.getAnnotationMetadata());
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(bd);
assertNotNull("resolveScopeMetadata(..) must *never* return null.", scopeMetadata);
assertEquals("request", scopeMetadata.getScopeName());
assertEquals(NO, scopeMetadata.getScopedProxyMode());
}
@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 asmAnnotationMetadataForSubclass() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(AnnotatedComponentSubClass.class.getName());
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
doTestSubClassAnnotationInfo(metadata);
}
@Test
public void interfaceThroughSuperClassMatch() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
String classUnderTest = "org.springframework.core.type.AssignableTypeFilterTests$SomeDaoLikeImpl";
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(classUnderTest);
AssignableTypeFilter filter = new AssignableTypeFilter(JdbcDaoSupport.class);
assertTrue(filter.match(metadataReader, metadataReaderFactory));
ClassloadingAssertions.assertClassNotLoaded(classUnderTest);
}
@Test
public void testInheritedAnnotationFromBaseClassDoesMatch() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
String classUnderTest = "org.springframework.core.type.AnnotationTypeFilterTests$SomeSubclassOfSomeComponent";
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(classUnderTest);
AnnotationTypeFilter filter = new AnnotationTypeFilter(InheritedAnnotation.class);
assertTrue(filter.match(metadataReader, metadataReaderFactory));
ClassloadingAssertions.assertClassNotLoaded(classUnderTest);
}
@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
public void testDirectAnnotationMatch() throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
String classUnderTest = "org.springframework.core.type.AnnotationTypeFilterTests$SomeComponent";
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(classUnderTest);
AnnotationTypeFilter filter = new AnnotationTypeFilter(InheritedAnnotation.class);
assertTrue(filter.match(metadataReader, metadataReaderFactory));
ClassloadingAssertions.assertClassNotLoaded(classUnderTest);
}
@Test
public void customRequestScopeWithAttributeViaAsm() throws IOException {
MetadataReaderFactory readerFactory = new SimpleMetadataReaderFactory();
MetadataReader reader = readerFactory.getMetadataReader(AnnotatedWithCustomRequestScopeWithAttributeOverride.class.getName());
AnnotatedBeanDefinition bd = new AnnotatedGenericBeanDefinition(reader.getAnnotationMetadata());
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(bd);
assertNotNull("resolveScopeMetadata(..) must *never* return null.", scopeMetadata);
assertEquals("request", scopeMetadata.getScopeName());
assertEquals(TARGET_CLASS, scopeMetadata.getScopedProxyMode());
}
private void assertNoMatch(String type, String typePattern) throws Exception {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(type);
AspectJTypeFilter filter = new AspectJTypeFilter(typePattern, getClass().getClassLoader());
assertFalse(filter.match(metadataReader, metadataReaderFactory));
ClassloadingAssertions.assertClassNotLoaded(type);
}
@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 the given bean definition is a candidate for a configuration class
* (or a nested component class declared within a configuration/component class,
* to be auto-registered as well), and mark it accordingly.
* @param beanDef the bean definition to check
* @param metadataReaderFactory the current factory in use by the caller
* @return whether the candidate qualifies as (any kind of) configuration class
*/
public static boolean checkConfigurationClassCandidate(
BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
String className = beanDef.getBeanClassName();
if (className == null || beanDef.getFactoryMethodName() != null) {
return false;
}
AnnotationMetadata metadata;
if (beanDef instanceof AnnotatedBeanDefinition &&
className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
// Can reuse the pre-parsed metadata from the given BeanDefinition...
metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
}
else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
// Check already loaded Class if present...
// since we possibly can't even load the class file for this Class.
Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
if (BeanFactoryPostProcessor.class.isAssignableFrom(beanClass) ||
BeanPostProcessor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass) ||
EventListenerFactory.class.isAssignableFrom(beanClass)) {
return false;
}
metadata = AnnotationMetadata.introspect(beanClass);
}
else {
try {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
metadata = metadataReader.getAnnotationMetadata();
}
catch (IOException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Could not find class file for introspecting configuration annotations: " +
className, ex);
}
return false;
}
}
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
else if (config != null || isConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
else {
return false;
}
// It's a full or lite configuration candidate... Let's determine the order value, if any.
Integer order = getOrder(metadata);
if (order != null) {
beanDef.setAttribute(ORDER_ATTRIBUTE, order);
}
return true;
}
@Bean
public StubManager newStubManager() {
System.out.println("Initializing StubManager...");
StubManager stubManager = new StubManager();
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
try {
Resource[] resources =
resourcePatternResolver.getResources(
ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
+ ClassUtils.convertClassNameToResourcePath("com.webank")
+ "/**/*.class");
logger.debug("Total {} resources", resources.length);
MetadataReaderFactory metadataReaderFabtFactory = new SimpleMetadataReaderFactory();
for (Resource resource : resources) {
logger.debug("Scan stub plugin: {}", resource.getURI().toString());
MetadataReader metadataReader =
metadataReaderFabtFactory.getMetadataReader(resource);
if (metadataReader.getAnnotationMetadata().hasAnnotation(Stub.class.getName())) {
Map<String, Object> attributes =
metadataReader
.getAnnotationMetadata()
.getAnnotationAttributes(Stub.class.getName());
String name = (String) attributes.get("value");
if (stubManager.hasDriver(name)) {
throw new Exception(
"Duplicate stub plugin["
+ name
+ "]: "
+ resource.getURI().toString());
}
Class<?> claz = Class.forName(metadataReader.getClassMetadata().getClassName());
StubFactory stubFactory =
(StubFactory) claz.getDeclaredConstructor().newInstance();
stubManager.addStubFactory(name, stubFactory);
logger.info("Load stub plugin[" + name + "]: " + resource.getURI().toString());
}
}
} catch (Exception e) {
String errorMsg = "Loading stub error: " + e;
logger.error(errorMsg);
System.exit(-1);
}
return stubManager;
}
private void scanPackage(SpringPersistenceUnitInfo scannedUnit, String pkg) {
if (this.componentsIndex != null) {
Set<String> candidates = new HashSet<>();
for (AnnotationTypeFilter filter : entityTypeFilters) {
candidates.addAll(this.componentsIndex.getCandidateTypes(pkg, filter.getAnnotationType().getName()));
}
candidates.forEach(scannedUnit::addManagedClassName);
Set<String> managedPackages = this.componentsIndex.getCandidateTypes(pkg, "package-info");
managedPackages.forEach(scannedUnit::addManagedPackage);
return;
}
try {
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
ClassUtils.convertClassNameToResourcePath(pkg) + CLASS_RESOURCE_PATTERN;
Resource[] resources = this.resourcePatternResolver.getResources(pattern);
MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver);
for (Resource resource : resources) {
if (resource.isReadable()) {
MetadataReader reader = readerFactory.getMetadataReader(resource);
String className = reader.getClassMetadata().getClassName();
if (matchesFilter(reader, readerFactory)) {
scannedUnit.addManagedClassName(className);
if (scannedUnit.getPersistenceUnitRootUrl() == null) {
URL url = resource.getURL();
if (ResourceUtils.isJarURL(url)) {
scannedUnit.setPersistenceUnitRootUrl(ResourceUtils.extractJarFileURL(url));
}
}
}
else if (className.endsWith(PACKAGE_INFO_SUFFIX)) {
scannedUnit.addManagedPackage(
className.substring(0, className.length() - PACKAGE_INFO_SUFFIX.length()));
}
}
}
}
catch (IOException ex) {
throw new PersistenceException("Failed to scan classpath for unlisted entity classes", ex);
}
}