AOP или APT для переопределения методов из суперклассов

У меня есть большая библиотека компонентов калитки, которые снабжены пользовательской аннотацией@ReferencedResource или другая аннотация@ReferencedResources, который имеетReferencedResouce[] value() параметр, чтобы разрешить несколько аннотаций.

Вот пример кода:

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

Пока что пользуюсьсклонный проверить, что ссылочные ресурсы действительно существуют. Например.

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

приведет к ошибке компиляции, если файлjs/behaviors/promoteSelectOptions.js можно найти на пути к классам. Эта часть работает хорошо.

Теперь я также поклонник DRY и хотел бы использовать ту же аннотацию для фактического внедрения ресурсов в объекты при их создании. Используя AspectJ, я реализовал часть этого.

Аннотированные объекты всегда являются экземплярамиСоставная часть или жеAbstractBehavior.

Для компонентов все просто, просто сопоставьте после конструктора. Вот совет, который делает это:

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);
    }
}

Однако для поведения мне нужно прикрепить ресурсы к ответу, а не к самому поведению. Вот точки, которые я использую:

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

И вот совет:

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);
    }
}

Это также хорошо работает, если класс переопределяетrenderHead (ответ) метод, но во многих случаях это просто не нужно, потому что суперкласс уже реализует базовую функциональность, в то время как дочерний класс только добавляет некоторую конфигурацию. Поэтому одним из решений было бы позволить этим классам определить метод, подобный этому:

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

Я бы не хотел этого, потому что это мертвый код, но в настоящее время это единственная рабочая опция, которую я вижу, поэтому я ищу другие решения.

РЕДАКТИРОВАТЬ:

Я создал рабочее решение, используя APT и Sun Javac Call. Однако это приводит к следующей проблеме:Запуск APT и AspectJ в одном проекте с использованием maven.

В любом случае, как только у меня будет свободное время, я опубликую ответ на этот вопрос (или его части).

Ответы на вопрос(1)

Ваш ответ на вопрос