It's a service that helps find specific annotations used in a project.
I encountered a situation in a Java project where I needed to find classes that are using a specific annotation. I thought creating a simple feature similar to Spring Framework's component scanner could be very useful in many cases, so I decided to give it a try.
Go to 🚀 maven central repository
implementation group: 'io.github.mainmethod0126', name: 'annotation-scanner', version: '0.0.4'
- short
implementation 'io.github.mainmethod0126:annotation-scanner:0.0.4'
- kotlin
implementation("io.github.mainmethod0126:annotation-scanner:0.0.4")
<dependency>
<groupId>io.github.mainmethod0126</groupId>
<artifactId>annotation-scanner</artifactId>
<version>0.0.4</version>
</dependency>
public class AnnotationScannerTest {
@Test
@DisplayName("This service locates classes that are using a specific annotation within the given package and its subpackages.")
public void testScanClass_whenNormalParam_thenSuccess() throws ClassNotFoundException {
// given
String rootPackage = "io.github.mainmethod0126.annotation.scanner";
// when
AnnotationScanner annotationScanner = new AnnotationScanner(rootPackage);
List<Class<?>> classes = annotationScanner.scanClass(TestAnnotation.class);
for (Class<?> clazz : classes) {
System.out.println(clazz.getName());
}
// then
assertThat(classes).isNotNull().isNotEmpty();
}
}
When using the Spring framework, it is often necessary to specify the class loader as Spring-specific class loaders are frequently utilized.
public class AnnotationScannerTest {
@Test
@DisplayName("This service locates classes that are using a specific annotation within the given package and its subpackages.")
public void testScanClass_whenNormalParam_thenSuccess() throws ClassNotFoundException {
// given
String rootPackage = "io.github.mainmethod0126.annotation.scanner";
// when
AnnotationScanner annotationScanner = new AnnotationScanner(rootPackage);
List<Class<?>> classes = annotationScanner.scanClass(TestAnnotation.class, this.getClass().getClassLoader());
for (Class<?> clazz : classes) {
System.out.println(clazz.getName());
}
// then
assertThat(classes).isNotNull().isNotEmpty();
}
}
# Standard output
io.github.mainmethod0126.annotation.scanner.TestOrder
io.github.mainmethod0126.annotation.scanner.TestProduct
io.github.mainmethod0126.annotation.scanner.TestUser
When considering the scenario where the 'User' class exists, if two different class loaders, A and B, each load the 'User' class separately, comparing the types of the 'User' class loaded by different class loaders would result in them being recognized as distinct classes. In such cases, when a regular user anticipates the recognition of the same class, unexpected outcomes can arise.