AOP o APT para anular métodos de superclases

Tengo una gran biblioteca de componentes de wicket que están anotados con una anotación personalizada@ReferencedResource u otra anotación@ReferencedResourcesque tiene unReferencedResouce[] value() parámetro para permitir múltiples anotaciones.

Aquí hay un fragmento de código de muestra:

@ReferencedResources({
    @ReferencedResource(value = Libraries.MOO_TOOLS, type = ResourceType.JAVASCRIPT),
    @ReferencedResource(value = "behaviors/promoteSelectOptions", type = ResourceType.JAVASCRIPT) })
public class PromoteSelectOptionsBehavior extends AbstractBehavior{
 ...
}

Hasta ahora, usoapto para verificar que los recursos referenciados realmente existan. P.ej.

@ReferencedResource(value = "behaviors/promoteSelectOptions",
                     type = ResourceType.JAVASCRIPT)

provocará un error de compilación a menos que el archivojs/behaviors/promoteSelectOptions.js se puede encontrar en la ruta de clase. Esta parte funciona muy bien.

Ahora también soy fanático de DRY y me gustaría usar la misma anotación para inyectar realmente los recursos en los Objetos cuando se crean. Usando AspectJ, he implementado una parte de esto.

Los objetos anotados son siempre instancias deComponente oComportamiento abstracto.

Para los componentes, las cosas son fáciles, solo coinciden después del constructor. Aquí hay un consejo que hace esto:

pointcut singleAnnotation() : @within(ReferencedResource);

pointcut multiAnnotation() : @within(ReferencedResources);

after() : execution(Component+.new(..)) && (singleAnnotation() || multiAnnotation()){
    final Component component = (Component) thisJoinPoint.getTarget();
    final Collection<ReferencedResource> resourceAnnotations =
        // gather annotations from cache
        this.getResourceAnnotations(component.getClass());
    for(final ReferencedResource annotation : resourceAnnotations){
        // helper utility that handles the creation of statements like
        // component.add(JavascriptPackageResource.getHeaderContribution(path))
        this.resourceInjector.inject(component, annotation);
    }
}

Sin embargo, para los comportamientos, necesito adjuntar los recursos a una respuesta, no al comportamiento en sí. Aquí están los puntos de corte que uso:

pointcut renderHead(IHeaderResponse response) :
    execution(* org.apache.wicket.behavior.AbstractBehavior+.renderHead(*))
        && args(response);

Y aquí está el consejo:

before(final IHeaderResponse response) : 
    renderHead(response) && (multiAnnotation() || singleAnnotation()) {
    final Collection<ReferencedResource> resourceAnnotations =
        this.getResourceAnnotations(thisJoinPoint.getTarget().getClass());
    for(final ReferencedResource resource : resourceAnnotations){
        this.resourceInjector.inject(response, resource);
    }
}

Esto también funciona bien si la clase anula elrenderHead (respuesta) método, pero en muchos casos eso no es necesario porque una superclase ya implementa la funcionalidad base mientras que la clase secundaria solo agrega alguna configuración. Entonces, una solución sería dejar que estas clases definan un método como este:

@Override
public void renderHead(IHeaderResponse response){
    super.renderHead(response);
}

Odiaría esto, porque este es un código muerto, pero actualmente esta es la única opción de trabajo que veo, así que estoy buscando otras soluciones.

EDITAR:

He creado una solución de trabajo utilizando llamadas APT y sun javac. Sin embargo, esto lleva al siguiente problema:Ejecutando APT y AspectJ en el mismo proyecto usando maven.

De todos modos, tan pronto como tenga algo de tiempo libre, publicaré la respuesta a esta pregunta (o partes de ella).

Respuestas a la pregunta(1)

Su respuesta a la pregunta