2010-11-05 10 views
30

Deseo obtener una lista completa de clases en la aplicación que están anotadas con la anotación @Custom. ¿Cuál es el mejor mecanismo para esta operación?¿Cómo crear una lista de clases anotadas con mi anotación personalizada?

ps. Por ejemplo, ¿cómo las implementaciones de JAX-RS encuentran todas las clases anotadas con @Path? Me gustaría usar el mismo mecanismo.

+0

¿Está utilizando un IDE? – thejh

+0

¿Desea buscar en el código fuente (.java) o en el código compilado (.class)? –

+0

No, no uso ningún IDE. Solo estoy interesado en el código compilado en mi JAR. – yegor256

Respuesta

0

Ejecuta un hallazgo en tu IDE en la fuente, Si intentas hacer esto en clases compiladas deberías haberles agregado un método para soportar esto, incluso si descompilaste las clases no creo que las anotaciones o los comentarios muestren arriba.

+1

Las anotaciones aparecen en Java de código byte –

+0

@ Brian sí, si de la anotación '' @ Retention' es RUNTIME' –

+0

... si se definen con '@Retention (DURACIÓN)' –

2

Como usted probablemente sabe por ahora, Java no tiene manera de enumerar todos los paquetes o las clases en cada paquete. Entonces tienes que hacerlo de la manera "difícil". Opciones:

  1. utilizar una herramienta como grep para buscar la anotación. Ventaja: rápido, simple. Inconvenientes: Podría devolver falsos positivos (como las clases donde la anotación está comentada).

  2. compilar el código y procesar el resultado con javap. Eso funciona en el nivel de bytecode [*]. Le da resultados precisos pero la salida de javap no está realmente destinada al procesamiento automático.

  3. utilizar una biblioteca de código de bytes como ASM. No es para cardíacos, pero le permite acceder también a otros datos (como interfaces, campos, etc.) implementados en relación con la anotación.

  4. Última opción: Eclipse usa su propio compilador de Java que puede construir un código AST a partir de Java (incluso si el código no se compila). Ventaja sobre ASM: obtienes un modelo para código Java gratis. Hace que ciertas operaciones sean más simples. No obstante, no es tan fácil de configurar. See my blog for an example.

[*]: la anotación debe tener Retention.RUNTIME para que funcione.

+0

Primera opción = arggghh. Todos los demás: +1 –

+0

¿Cuál de sus opciones están usando las implementaciones JAX-RS, por ejemplo, Jersey, para encontrar todas las clases con anotaciones '@ Path'? – yegor256

+0

¿Desea presentar pruebas de su reclamo de que no hay forma? ¿Especialmente a la luz de la biblioteca a la que me he vinculado en mi respuesta? – meriton

0

La forma más fácil sería utilizar un IDE as Jesus suggested.

Pero se puede también

Cuidado: todo esto es complicado. La solución de AspectJ debería ser la más simple.

3

Usted debe echar un vistazo a Scannotation.

+0

Parece una buena opción. Voy a intentar más tarde – rpax

21

Por lo general, esto se hace mediante el proceso llamado exploración classpath. En general, los cargadores de clases no permiten el escaneo a través de todas las clases en el classpath.Pero generalmente el único cargador de clases utilizado es UrlClassLoader desde el que podemos recuperar la lista de directorios y archivos jar (consulte getURLs) y abrirlos uno por uno para enumerar las clases disponibles.

Este enfoque es implementado por bibliotecas como Scannotation y Reflections.

Otro enfoque es utilizar Java Pluggable Annotation Processing API para escribir el procesador de anotaciones que recogerá todas las clases anotadas en tiempo de compilación y compilará el archivo de índice para su uso en tiempo de ejecución.

El mecanismo anterior se implementa en la biblioteca ClassIndex.

El uso del análisis de classpath suele ser dos órdenes de magnitud más lento que la indexación en tiempo de compilación. Ver this benchmark.

10

Sé que esta es una pregunta antigua, pero me encontré con ella en mi propia búsqueda para el escaneo de classpath y encontré otra buena respuesta, así que la estoy agregando aquí.

Google Guava tiene un objeto ClassPath que proporciona la exploración ruta de clases "mejor esfuerzo" (que es todos ninguna oferta de servicios de exploración ruta de clase, en realidad). Como Guava es una biblioteca de utilidades ampliamente adoptada y cuidadosamente mantenida, esta es una excelente opción para proyectos que ya sea que (a) ya estén usando Guava, o (b) necesiten una biblioteca estable en la que puedan confiar para el escaneo de classpath.

1

classindex es una biblioteca de análisis de anotaciones en tiempo de compilación, implementada mediante un procesador de anotación.

3

Usted podría intentar mi biblioteca FastClasspathScanner:

List<String> classNames = new FastClassPathScanner("com.mypackage") 
    .scan() 
    .getNamesOfClassesWithAnnotation(Custom.class); 
Cuestiones relacionadas