2012-03-05 4 views
4

Я хочу, чтобы мой класс реализовал интерфейс, но я хочу обеспечить реализацию методов с использованием ITD в аспекте. Возможно ли это?AspectJ ITDs: реализация общего интерфейса

Интерфейс:

public interface CloningService<T> { 
    public T clone(T object); 
} 

Реализация по умолчанию:

public class DefaultCloningServiceImpl implements CloningService<T> { 
    public T clone(T object) { 
     // implementation of the clone method 
    } 
} 

Конкретная реализация:

public class PersonService implements CloningService<Person> { 
    // no code (!) 
} 

Класс PersonService бы заявить, что он реализует интерфейс CloningService, но фактическая реализация методов быть предоставлен в DefaultCloningServiceImpl, и аспект будет представлен им в PersonService.

Я следил за примером на Eclipse.com, и я попытался использовать @DeclareParents для достижения вышеуказанной функциональности. Тем не менее, я получал ошибку компилятора от AspectJ, которая имела отношение к дженерикам. Это как если бы аннотация @DeclareParents не ожидала использования дженериков ...

Спасибо.

ответ

2

Я бы порекомендовал вам использовать аспект типа stylej для решения этого, а не стиля аннотации.

Это может быть сделано просто, имея аспект, как это:

aspect CloningServiceAspect { 
    declare parents : PersonService extends DefaultCloningServiceImpl<Object>; 
} 

Чтобы сделать это более общим и присоединяют к аннотациям, вы можете сделать что-то вроде этого:

aspect CloningServiceAspect { 
    declare parents : (@CloningService *) extends DefaultCloningServiceImpl<Object>; 
} 

И если вы хотели бы упаковать это в отдельную банку, просто убедитесь, что вы добавили весь код, который вы хотите переплетать, добавляет эту банку в свой путь к аспекту (если вы используете компиляцию во времени).

+0

Андрей, спасибо за ваш ответ. Это звучит неплохо, но у меня есть два вопроса: (1) не является ли стиль аннотации стиль? мое доверие заключалось в том, что это была лучшая практика. (2) предлагаемый вами код расширяет PersonService, но я хочу расширить все службы, отмеченные аннотацией (или, тем не менее, действительно), потому что я хочу поместить эту логику в отдельный JAR. есть ли решение, которое будет работать лучше для меня? – anton1980

+1

Нет, стиль аннотации не является предпочтительным. По одной причине инструменты не работают также с стилем аннотации. Кроме того, есть вещи, которые просто невозможно сделать с помощью стиля аннотации (например, объявления интертипа). Основная причина, по которой люди выбирают стиль аннотации над стилем кода, заключается в том, что они хотят, чтобы их код был скомпилирован стандартным компилятором Java (а затем они запускали ткача над ним). –

+0

Развернутый мой ответ выше, чтобы более полно ответить на ваш вопрос. –

1

Я нашел решение! Она включает в себя использование @DeclareMixin аннотации от AspectJ смешать реализацию по умолчанию клона() метод:

@Aspect 
public class CloningServiceAspect { 
    @DeclareMixin(value = "(@CloningService *)") 
    public static CloningService<?> createImplementation() { 
     return new DefaultCloningServiceImpl<Object>(); 
    } 
} 

И тогда моя служба помечается @CloningService вместо реализации интерфейса:

@CloningService 
public class PersonService { 
    // no code 
} 
Смежные вопросы