6

He creado una anotación, la he aplicado a un DTO y he escrito un Javatat style annotationProcessor. Puedo ver cómo hacer que el procesador de anotaciones escriba un nuevo archivo fuente, que no es lo que quiero hacer, no puedo ver ni averiguar cómo modificar la clase existente (lo ideal es modificar el código de bytes). La modificación es realmente bastante trivial, todo lo que quiero que el procesador haga es insertar un nuevo getter y setter donde el nombre proviene del valor de la anotación que se está procesando.¿Cómo se usa Java 1.6 Annotation Processing para realizar el tiempo de compilación?

Mi procesador de anotaciones se ve así;

@SupportedSourceVersion(SourceVersion.RELEASE_6) 
@SupportedAnnotationTypes({ "com.kn.salog.annotation.AggregateField" }) 
public class SalogDTOAnnotationProcessor extends AbstractProcessor { 

    @Override 
    public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) { 
     //do some stuff 
    } 
} 

Respuesta

-2

Usted tiene que extender el compilador javac para esto, lo que significa la construcción de su programa no será tan portátil como una aplicación normal. Vea http://weblogs.java.net/blog/cayhorstmann/archive/2006/06/say_no_to_prope.html para más detalles sobre cómo alguien logró esto.

+1

Sin duda es una solución, pero estoy bastante seguro de que no es la única solución. Lo que quiero hacer podría ser hecho por varios frameworks/conjuntos de herramientas existentes, por ejemplo, javassist. Estaba tratando de evitar introducir una dependencia que no parece ser estrictamente necesaria, sin embargo, la introducción del procesamiento de anotaciones en JDK1.6 parecía que la funcionalidad de javassist estaba siendo procesada. Tal vez estaba equivocado y aún necesito un Herramienta de terceros para realizar el tiempo de compilación. – Steve

6

Por diseño, la función de procesamiento de anotación no permite la modificación directa del código fuente que se está procesando. Sin embargo, se pueden generar subclases del tipo que se está procesando o la superclase del tipo que se está procesando. Con un poco de planificación, esto permite algunos de los efectos de modificar el tipo en cuestión. He escrito un ejemplo de cómo esto puede encajar; ver this blog entry para una explicación más detallada y un código de muestra.

6

Está buscando "Instrumentación", que es lo que frameworks como AspectJ do. En este caso, debe especificar un jar en la línea de comando con la opción "-agent", y luego tener la posibilidad de filtrar todas las clases cargadas. Durante este paso de filtro, puede buscar anotaciones y modificar el bytecode antes de que se cargue en la máquina virtual. Las bibliotecas para hacer la modificación del código de bytes actual incluyen "asm", y tal vez los envoltorios de alto nivel "cglib" y "javassist". Incluso podría precompilar sus clases para generar una lista de clases que usted debe instrumentar, para que el filtrado sea un poco más rápido al principio.

Consulte java.lang.instrumentation para obtener más información.

4

usted tiene que utilizar las clases del compilador interno - algo de inspiración:

pero es arriesgada. Su programa compilará solo en Sun/OpenJDK y puede haber problemas en versiones futuras (la API interna puede cambiar). Aunque una vez compilado, es un bytecode estándar y se ejecutará en todas partes.

BTW: si desea usarlo en Eclipse, debe agregar algo de soporte especial porque Eclipse usa un compilador no estándar. Su diseño debe ser más complejo y debe agregar un nivel de abstracción a su procesador, como Lombok.

+0

Esos son ejemplos maravillosos. ¡Gracias! –

Cuestiones relacionadas