下面列出了怎么用org.springframework.core.type.StandardAnnotationMetadata的API类实例代码及写法,或者点击链接到github查看源代码。
public static void main(String[] args) throws IOException {
// 读取 @TransactionService AnnotationMetadata 信息
AnnotationMetadata annotationMetadata = new StandardAnnotationMetadata(TransactionalServiceStandardAnnotationMetadataBootstrap.class);
// 获取所有的元注解类型(全类名)集合
Set<String> metaAnnotationTypes = annotationMetadata.getAnnotationTypes()
.stream() // TO Stream
.map(annotationMetadata::getMetaAnnotationTypes) // 读取单注解的元注解类型集合
.collect(LinkedHashSet::new, Set::addAll, Set::addAll); // 合并元注解类型(全类名)集合
metaAnnotationTypes.forEach(metaAnnotation -> { // 读取所有元注解类型
// 读取元注解属性信息
Map<String, Object> annotationAttributes = annotationMetadata.getAnnotationAttributes(metaAnnotation);
if (!CollectionUtils.isEmpty(annotationAttributes)) {
annotationAttributes.forEach((name, value) ->
System.out.printf("注解 @%s 属性 %s = %s\n", ClassUtils.getShortName(metaAnnotation), name, value));
}
});
}
@SuppressWarnings("unused")
@Override
protected AbstractFunctionExecutionConfigurationSource newAnnotationBasedFunctionExecutionConfigurationSource(
AnnotationMetadata annotationMetadata) {
StandardAnnotationMetadata metadata =
new StandardAnnotationMetadata(getConfiguration(), true);
return new AnnotationFunctionExecutionConfigurationSource(metadata) {
@Override
public Iterable<String> getBasePackages() {
return AutoConfigurationPackages.get(getBeanFactory());
}
};
}
@Test
public void testViewScopedClass() {
GenericApplicationContext acx = new GenericApplicationContext();
AnnotationConfigUtils.registerAnnotationConfigProcessors(acx);
acx.registerBeanDefinition("viewScopedClass", new AnnotatedGenericBeanDefinition(
new StandardAnnotationMetadata(ViewScopedClass.class)));
acx.registerBeanDefinition("scopedBeansConfiguration", new RootBeanDefinition(
ScopedBeansConfiguration.class));
acx.addBeanFactoryPostProcessor(JsfScopeAnnotationsAutoConfiguration.jsfScopeAnnotationsConfigurer(acx.getEnvironment()));
acx.addBeanFactoryPostProcessor(CdiScopeAnnotationsAutoConfiguration.cdiScopeAnnotationsConfigurer(acx.getEnvironment()));
acx.refresh();
assertThat(acx.getBeanDefinition("viewScopedClass").getScope())
.isEqualTo(ViewScope.SCOPE_VIEW);
assertThat(acx.getBeanDefinition("viewScopedBean").getScope())
.isEqualTo(ViewScope.SCOPE_VIEW);
}
@Test
public void testSessionScopedClass() {
GenericApplicationContext acx = new GenericApplicationContext();
AnnotationConfigUtils.registerAnnotationConfigProcessors(acx);
acx.registerBeanDefinition("sessionScopedClass", new AnnotatedGenericBeanDefinition(
new StandardAnnotationMetadata(SessionScopedClass.class)));
acx.registerBeanDefinition("scopedBeansConfiguration", new RootBeanDefinition(
ScopedBeansConfiguration.class));
acx.addBeanFactoryPostProcessor(JsfScopeAnnotationsAutoConfiguration.jsfScopeAnnotationsConfigurer(acx.getEnvironment()));
acx.addBeanFactoryPostProcessor(CdiScopeAnnotationsAutoConfiguration.cdiScopeAnnotationsConfigurer(acx.getEnvironment()));
acx.refresh();
assertThat(acx.getBeanDefinition("sessionScopedClass").getScope())
.isEqualTo(WebApplicationContext.SCOPE_SESSION);
assertThat(acx.getBeanDefinition("sessionScopedBean").getScope())
.isEqualTo(WebApplicationContext.SCOPE_SESSION);
}
@Test
public void testNoScopedClass() {
GenericApplicationContext acx = new GenericApplicationContext();
AnnotationConfigUtils.registerAnnotationConfigProcessors(acx);
acx.registerBeanDefinition("noScopedClass", new AnnotatedGenericBeanDefinition(
new StandardAnnotationMetadata(NoScopedClass.class)));
acx.registerBeanDefinition("scopedBeansConfiguration", new RootBeanDefinition(
ScopedBeansConfiguration.class));
acx.addBeanFactoryPostProcessor(JsfScopeAnnotationsAutoConfiguration.jsfScopeAnnotationsConfigurer(acx.getEnvironment()));
acx.addBeanFactoryPostProcessor(CdiScopeAnnotationsAutoConfiguration.cdiScopeAnnotationsConfigurer(acx.getEnvironment()));
acx.refresh();
assertThat(acx.getBeanDefinition("noScopedClass").getScope())
.isEqualTo("");
assertThat(acx.getBeanDefinition("noScopedBean").getScope())
.isEqualTo("");
}
/**
* Retrieve the metadata for all <code>@Bean</code> methods.
*/
private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass) {
AnnotationMetadata original = sourceClass.getMetadata();
Set<MethodMetadata> beanMethods = original.getAnnotatedMethods(Bean.class.getName());
if (beanMethods.size() > 1 && original instanceof StandardAnnotationMetadata) {
// Try reading the class file via ASM for deterministic declaration order...
// Unfortunately, the JVM's standard reflection returns methods in arbitrary
// order, even between different runs of the same application on the same JVM.
try {
AnnotationMetadata asm =
this.metadataReaderFactory.getMetadataReader(original.getClassName()).getAnnotationMetadata();
Set<MethodMetadata> asmMethods = asm.getAnnotatedMethods(Bean.class.getName());
if (asmMethods.size() >= beanMethods.size()) {
Set<MethodMetadata> selectedMethods = new LinkedHashSet<>(asmMethods.size());
for (MethodMetadata asmMethod : asmMethods) {
for (MethodMetadata beanMethod : beanMethods) {
if (beanMethod.getMethodName().equals(asmMethod.getMethodName())) {
selectedMethods.add(beanMethod);
break;
}
}
}
if (selectedMethods.size() == beanMethods.size()) {
// All reflection-detected methods found in ASM method set -> proceed
beanMethods = selectedMethods;
}
}
}
catch (IOException ex) {
logger.debug("Failed to read class file via ASM for determining @Bean method order", ex);
// No worries, let's continue with the reflection metadata we started with...
}
}
return beanMethods;
}
/**
* Factory method to obtain a {@link SourceClass} from a {@link ConfigurationClass}.
*/
private SourceClass asSourceClass(ConfigurationClass configurationClass) throws IOException {
AnnotationMetadata metadata = configurationClass.getMetadata();
if (metadata instanceof StandardAnnotationMetadata) {
return asSourceClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass());
}
return asSourceClass(metadata.getClassName());
}
@Test
public void metadataFromImportsOneThenTwo() {
AnnotationMetadata importMetadata = new AnnotationConfigApplicationContext(
ConfigurationOne.class, ConfigurationTwo.class)
.getBean(MetadataHolder.class).importMetadata;
assertEquals(ConfigurationOne.class,
((StandardAnnotationMetadata) importMetadata).getIntrospectedClass());
}
@Test
public void metadataFromImportsTwoThenOne() {
AnnotationMetadata importMetadata = new AnnotationConfigApplicationContext(
ConfigurationTwo.class, ConfigurationOne.class)
.getBean(MetadataHolder.class).importMetadata;
assertEquals(ConfigurationOne.class,
((StandardAnnotationMetadata) importMetadata).getIntrospectedClass());
}
/**
* Create a new AnnotatedGenericBeanDefinition for the given annotation metadata,
* allowing for ASM-based processing and avoidance of early loading of the bean class.
* Note that this constructor is functionally equivalent to
* {@link org.springframework.context.annotation.ScannedGenericBeanDefinition
* ScannedGenericBeanDefinition}, however the semantics of the latter indicate that a
* bean was discovered specifically via component-scanning as opposed to other means.
* @param metadata the annotation metadata for the bean class in question
* @since 3.1.1
*/
public AnnotatedGenericBeanDefinition(AnnotationMetadata metadata) {
Assert.notNull(metadata, "AnnotationMetadata must not be null");
if (metadata instanceof StandardAnnotationMetadata) {
setBeanClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass());
}
else {
setBeanClassName(metadata.getClassName());
}
this.metadata = metadata;
}
/**
* Retrieve the metadata for all <code>@Bean</code> methods.
*/
private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass) {
AnnotationMetadata original = sourceClass.getMetadata();
Set<MethodMetadata> beanMethods = original.getAnnotatedMethods(Bean.class.getName());
if (beanMethods.size() > 1 && original instanceof StandardAnnotationMetadata) {
// Try reading the class file via ASM for deterministic declaration order...
// Unfortunately, the JVM's standard reflection returns methods in arbitrary
// order, even between different runs of the same application on the same JVM.
try {
AnnotationMetadata asm =
this.metadataReaderFactory.getMetadataReader(original.getClassName()).getAnnotationMetadata();
Set<MethodMetadata> asmMethods = asm.getAnnotatedMethods(Bean.class.getName());
if (asmMethods.size() >= beanMethods.size()) {
Set<MethodMetadata> selectedMethods = new LinkedHashSet<>(asmMethods.size());
for (MethodMetadata asmMethod : asmMethods) {
for (MethodMetadata beanMethod : beanMethods) {
if (beanMethod.getMethodName().equals(asmMethod.getMethodName())) {
selectedMethods.add(beanMethod);
break;
}
}
}
if (selectedMethods.size() == beanMethods.size()) {
// All reflection-detected methods found in ASM method set -> proceed
beanMethods = selectedMethods;
}
}
}
catch (IOException ex) {
logger.debug("Failed to read class file via ASM for determining @Bean method order", ex);
// No worries, let's continue with the reflection metadata we started with...
}
}
return beanMethods;
}
/**
* Factory method to obtain a {@link SourceClass} from a {@link ConfigurationClass}.
*/
private SourceClass asSourceClass(ConfigurationClass configurationClass) throws IOException {
AnnotationMetadata metadata = configurationClass.getMetadata();
if (metadata instanceof StandardAnnotationMetadata) {
return asSourceClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass());
}
return asSourceClass(metadata.getClassName());
}
public SourceClass(Object source) {
this.source = source;
if (source instanceof Class) {
this.metadata = new StandardAnnotationMetadata((Class<?>) source, true);
}
else {
this.metadata = ((MetadataReader) source).getAnnotationMetadata();
}
}
/**
* Create a new {@link ConfigurationClass} with the given name.
* @param clazz the underlying {@link Class} to represent
* @param beanName name of the {@code @Configuration} class bean
* @see ConfigurationClass#ConfigurationClass(Class, ConfigurationClass)
*/
public ConfigurationClass(Class<?> clazz, String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
this.metadata = new StandardAnnotationMetadata(clazz, true);
this.resource = new DescriptiveResource(clazz.getName());
this.beanName = beanName;
}
@Test
public void metadataFromImportsOneThenTwo() {
AnnotationMetadata importMetadata = new AnnotationConfigApplicationContext(
ConfigurationOne.class, ConfigurationTwo.class)
.getBean(MetadataHolder.class).importMetadata;
assertEquals(ConfigurationOne.class,
((StandardAnnotationMetadata) importMetadata).getIntrospectedClass());
}
@Test
public void metadataFromImportsTwoThenOne() {
AnnotationMetadata importMetadata = new AnnotationConfigApplicationContext(
ConfigurationTwo.class, ConfigurationOne.class)
.getBean(MetadataHolder.class).importMetadata;
assertEquals(ConfigurationOne.class,
((StandardAnnotationMetadata) importMetadata).getIntrospectedClass());
}
/**
* Create a new AnnotatedGenericBeanDefinition for the given annotation metadata,
* allowing for ASM-based processing and avoidance of early loading of the bean class.
* Note that this constructor is functionally equivalent to
* {@link org.springframework.context.annotation.ScannedGenericBeanDefinition
* ScannedGenericBeanDefinition}, however the semantics of the latter indicate that a
* bean was discovered specifically via component-scanning as opposed to other means.
* @param metadata the annotation metadata for the bean class in question
* @since 3.1.1
*/
public AnnotatedGenericBeanDefinition(AnnotationMetadata metadata) {
Assert.notNull(metadata, "AnnotationMetadata must not be null");
if (metadata instanceof StandardAnnotationMetadata) {
setBeanClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass());
}
else {
setBeanClassName(metadata.getClassName());
}
this.metadata = metadata;
}
public static boolean matches(ConditionContext context) {
Class<AuthorizationServerEndpointsConfigurationBeanCondition> type = AuthorizationServerEndpointsConfigurationBeanCondition.class;
Conditional conditional = AnnotationUtils.findAnnotation(type, Conditional.class);
StandardAnnotationMetadata metadata = new StandardAnnotationMetadata(type);
for (Class<? extends Condition> conditionType : conditional.value()) {
Condition condition = BeanUtils.instantiateClass(conditionType);
if (condition.matches(context, metadata)) {
return true;
}
}
return false;
}
private boolean isConfigurationType(Class<?> configurationType) {
if (configurationModelProvider != null) {
return configurationModelProvider.isConfigurationType(configurationType);
} else {
// fallback to the simplified logic
StandardAnnotationMetadata metadata = new StandardAnnotationMetadata(configurationType);
return metadata.isAbstract() && metadata.isIndependent() &&
configurationAnnotations.stream().anyMatch(a -> findAnnotation(configurationType, a) != null);
}
}
/**
* Retrieve the metadata for all <code>@Bean</code> methods.
*/
private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass) {
AnnotationMetadata original = sourceClass.getMetadata();
Set<MethodMetadata> beanMethods = original.getAnnotatedMethods(Bean.class.getName());
if (beanMethods.size() > 1 && original instanceof StandardAnnotationMetadata) {
// Try reading the class file via ASM for deterministic declaration order...
// Unfortunately, the JVM's standard reflection returns methods in arbitrary
// order, even between different runs of the same application on the same JVM.
try {
AnnotationMetadata asm =
this.metadataReaderFactory.getMetadataReader(original.getClassName()).getAnnotationMetadata();
Set<MethodMetadata> asmMethods = asm.getAnnotatedMethods(Bean.class.getName());
if (asmMethods.size() >= beanMethods.size()) {
Set<MethodMetadata> selectedMethods = new LinkedHashSet<MethodMetadata>(asmMethods.size());
for (MethodMetadata asmMethod : asmMethods) {
for (MethodMetadata beanMethod : beanMethods) {
if (beanMethod.getMethodName().equals(asmMethod.getMethodName())) {
selectedMethods.add(beanMethod);
break;
}
}
}
if (selectedMethods.size() == beanMethods.size()) {
// All reflection-detected methods found in ASM method set -> proceed
beanMethods = selectedMethods;
}
}
}
catch (IOException ex) {
logger.debug("Failed to read class file via ASM for determining @Bean method order", ex);
// No worries, let's continue with the reflection metadata we started with...
}
}
return beanMethods;
}
/**
* Factory method to obtain a {@link SourceClass} from a {@link ConfigurationClass}.
*/
private SourceClass asSourceClass(ConfigurationClass configurationClass) throws IOException {
AnnotationMetadata metadata = configurationClass.getMetadata();
if (metadata instanceof StandardAnnotationMetadata) {
return asSourceClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass());
}
return asSourceClass(metadata.getClassName());
}
public SourceClass(Object source) {
this.source = source;
if (source instanceof Class) {
this.metadata = new StandardAnnotationMetadata((Class<?>) source, true);
}
else {
this.metadata = ((MetadataReader) source).getAnnotationMetadata();
}
}
/**
* Create a new {@link ConfigurationClass} with the given name.
* @param clazz the underlying {@link Class} to represent
* @param beanName name of the {@code @Configuration} class bean
* @see ConfigurationClass#ConfigurationClass(Class, ConfigurationClass)
*/
public ConfigurationClass(Class<?> clazz, String beanName) {
Assert.hasText(beanName, "Bean name must not be null");
this.metadata = new StandardAnnotationMetadata(clazz, true);
this.resource = new DescriptiveResource(clazz.getName());
this.beanName = beanName;
}
/**
* Create a new AnnotatedGenericBeanDefinition for the given annotation metadata,
* allowing for ASM-based processing and avoidance of early loading of the bean class.
* Note that this constructor is functionally equivalent to
* {@link org.springframework.context.annotation.ScannedGenericBeanDefinition
* ScannedGenericBeanDefinition}, however the semantics of the latter indicate that a
* bean was discovered specifically via component-scanning as opposed to other means.
* @param metadata the annotation metadata for the bean class in question
* @since 3.1.1
*/
public AnnotatedGenericBeanDefinition(AnnotationMetadata metadata) {
Assert.notNull(metadata, "AnnotationMetadata must not be null");
if (metadata instanceof StandardAnnotationMetadata) {
setBeanClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass());
}
else {
setBeanClassName(metadata.getClassName());
}
this.metadata = metadata;
}
/**
* Create a new AnnotatedGenericBeanDefinition for the given annotation metadata,
* allowing for ASM-based processing and avoidance of early loading of the bean class.
* Note that this constructor is functionally equivalent to
* {@link org.springframework.context.annotation.ScannedGenericBeanDefinition
* ScannedGenericBeanDefinition}, however the semantics of the latter indicate that a
* bean was discovered specifically via component-scanning as opposed to other means.
* @param metadata the annotation metadata for the bean class in question
* @since 3.1.1
*/
public AnnotatedGenericBeanDefinition(AnnotationMetadata metadata) {
Assert.notNull(metadata, "AnnotationMetadata must not be null");
if (metadata instanceof StandardAnnotationMetadata) {
setBeanClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass());
}
else {
setBeanClassName(metadata.getClassName());
}
this.metadata = metadata;
}
/**
* Factory method to obtain a {@link SourceClass} from a {@link ConfigurationClass}.
*/
public SourceClass asSourceClass(ConfigurationClass configurationClass) throws IOException {
AnnotationMetadata metadata = configurationClass.getMetadata();
if (metadata instanceof StandardAnnotationMetadata) {
return asSourceClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass());
}
return asSourceClass(configurationClass.getMetadata().getClassName());
}
public SourceClass(Object source) {
this.source = source;
if (source instanceof Class<?>) {
this.metadata = new StandardAnnotationMetadata((Class<?>) source, true);
}
else {
this.metadata = ((MetadataReader) source).getAnnotationMetadata();
}
}
/**
* Create a new {@link ConfigurationClass} with the given name.
* @param clazz the underlying {@link Class} to represent
* @param beanName name of the {@code @Configuration} class bean
* @see ConfigurationClass#ConfigurationClass(Class, ConfigurationClass)
*/
public ConfigurationClass(Class<?> clazz, String beanName) {
Assert.hasText(beanName, "Bean name must not be null");
this.metadata = new StandardAnnotationMetadata(clazz, true);
this.resource = new DescriptiveResource(clazz.toString());
this.beanName = beanName;
}
@Test
public void metadataFromImportsOneThenTwo() {
AnnotationMetadata importMetadata = new AnnotationConfigApplicationContext(
ConfigurationOne.class, ConfigurationTwo.class)
.getBean(MetadataHolder.class).importMetadata;
assertEquals(ConfigurationOne.class,
((StandardAnnotationMetadata) importMetadata).getIntrospectedClass());
}
@Test
public void metadataFromImportsTwoThenOne() {
AnnotationMetadata importMetadata = new AnnotationConfigApplicationContext(
ConfigurationTwo.class, ConfigurationOne.class)
.getBean(MetadataHolder.class).importMetadata;
assertEquals(ConfigurationOne.class,
((StandardAnnotationMetadata) importMetadata).getIntrospectedClass());
}