simplemente solté un escáner súper rápido y ruta de clase ligera (git repo here) que no llama el cargador de clases para cargar las clases en la ruta de clase con el fin de determinar subclases, superclases, anotaciones, etc., sino que lee los encabezados de archivo de clase binarios directamente (inspirada por, pero más simple que, el escáner classpath de rmueller, vinculado en otro comentario).
Mi classpath scanner puede encontrar clases en la classpath que extienden una determinada superclase, que implementan una interfaz dada, o que tienen una anotación de clase determinada, y pueden encontrar archivos dentro de la classpath de cualquier tipo cuya ruta coincida con una expresión regular dada .
Aquí es un ejemplo de uso:
new FastClasspathScanner(new String[]
{ "com.xyz.widget", "com.xyz.gizmo" }) // Whitelisted package prefixes
.matchSubclassesOf(DBModel.class,
// c is a subclass of DBModel
c -> System.out.println("Found subclass of DBModel: " + c.getName()))
.matchClassesImplementing(Runnable.class,
// c is a class that implements Runnable
c -> System.out.println("Found Runnable: " + c.getName()))
.matchClassesWithAnnotation(RestHandler.class,
// c is a class annotated with @RestHandler
c -> System.out.println("Found RestHandler annotation on class: "
+ c.getName()))
.matchFilenamePattern("^template/.*\\.html",
// templatePath is a path on the classpath that matches the above pattern;
// inputStream is a stream opened on the file or zipfile entry.
// No need to close inputStream before exiting, it is closed by caller.
(templatePath, inputStream) -> {
try {
String template = IOUtils.toString(inputStream, "UTF-8");
System.out.println("Found template: " + absolutePath
+ " (size " + template.length() + ")");
} catch (IOException e) {
throw new RuntimeException(e);
}
})
.scan(); // Actually perform the scan
El escáner también registra la última modificada por última vez marca de tiempo de cualquier archivo o directorio encontrado, y se puede ver si esa última fecha y hora modificada en último lugar se ha incrementado (lo que indica que algo en la ruta de clase se ha actualizado), llamando al:
boolean classpathContentsModified =
fastClassPathScanner.classpathContentsModifiedSinceScan();
Esto puede ser usado para permitir dinámica de clase-recarga si se actualiza algo en la ruta de clase, por ejemplo, para apoyar a reemplazar en caliente de las clases de controlador de ruta en una Servidor web. La llamada anterior es varias veces más rápida que la llamada original para escanear(), ya que solo se deben verificar las marcas de tiempo de modificación.
Gracias por su información. ¿También sabe cómo escanear classpath para las clases cuyos campos tienen una anotación personalizada? – Javatar
@Javatar Utilice la API de reflexión de Java. .class.getFields() Para cada campo, invoque getAnnotation () –
@ArthurRonaldFDGarcia, ¿cómo puedo escanear 'sub package' de esa manera? – CycDemo