Add ClassFile implementation for class metadata

Prior to this commit, Spring Framework would allow two ways of getting
class metadata:
* `StandardClassMetadata`, using the Java reflection API
* `SimpleMetadataReaderFactory`, using ASM to read the class bytecode

This commit adds a new implementation for this feature, this time using
the new `ClassFile` API which is taken out of preview in Java 24.

See gh-33616
This commit is contained in:
Brian Clozel
2024-11-28 16:27:28 +01:00
parent 28273b9309
commit 4f260a4511
11 changed files with 916 additions and 7 deletions

View File

@@ -146,8 +146,8 @@ public abstract class AbstractAnnotationMetadataTests {
@Test
void getSuperClassNameWhenHasNoSuperClassReturnsNull() {
assertThat(get(Object.class).getSuperClassName()).isNull();
assertThat(get(TestInterface.class).getSuperClassName()).isNull();
assertThat(get(TestSubInterface.class).getSuperClassName()).isNull();
assertThat(get(TestInterface.class).getSuperClassName()).isIn(null, "java.lang.Object");
assertThat(get(TestSubInterface.class).getSuperClassName()).isIn(null, "java.lang.Object");
}
@Test
@@ -210,6 +210,17 @@ public abstract class AbstractAnnotationMetadataTests {
assertThat(attributes.get("size")).containsExactlyInAnyOrder(1, 2);
}
@Test
void getComplexAttributeTypesReturnsAll() {
MultiValueMap<String, Object> attributes =
get(WithComplexAttributeTypes.class).getAllAnnotationAttributes(ComplexAttributes.class.getName());
assertThat(attributes).containsOnlyKeys("names", "count", "type");
assertThat(attributes.get("names")).hasSize(1);
assertThat(attributes.get("names").get(0)).isEqualTo(new String[]{"first", "second"});
assertThat(attributes.get("count")).containsExactlyInAnyOrder(TestEnum.ONE);
assertThat(attributes.get("type")).containsExactlyInAnyOrder(TestEnum.class);
}
@Test
void getAnnotationTypesReturnsDirectAnnotations() {
AnnotationMetadata metadata = get(WithDirectAnnotations.class);
@@ -407,4 +418,22 @@ public abstract class AbstractAnnotationMetadataTests {
}
@ComplexAttributes(names = {"first", "second"}, count = TestEnum.ONE, type = TestEnum.class)
public static class WithComplexAttributeTypes {
}
@Retention(RetentionPolicy.RUNTIME)
public @interface ComplexAttributes {
String[] names();
TestEnum count();
Class<?> type();
}
public enum TestEnum {
ONE, TWO, THREE
}
}

View File

@@ -30,9 +30,8 @@ class SimpleAnnotationMetadataTests extends AbstractAnnotationMetadataTests {
@Override
protected AnnotationMetadata get(Class<?> source) {
try {
return new SimpleMetadataReaderFactory(
source.getClassLoader()).getMetadataReader(
source.getName()).getAnnotationMetadata();
return MetadataReaderFactory.create(source.getClassLoader())
.getMetadataReader(source.getName()).getAnnotationMetadata();
}
catch (Exception ex) {
throw new IllegalStateException(ex);