Reputation: 1009
I want my class to implement an interface, but I want to provide the implementation of the methods using ITD in an aspect. Is this possible?
Interface:
public interface CloningService<T> {
public T clone(T object);
}
Default implementation:
public class DefaultCloningServiceImpl implements CloningService<T> {
public T clone(T object) {
// implementation of the clone method
}
}
Specific implementation:
public class PersonService implements CloningService<Person> {
// no code (!)
}
The class PersonService would declare that it implements the CloningService interface, but the actual implementation of the methods would be provided in DefaultCloningServiceImpl and an aspect would introduce them to PersonService.
I followed the example on Eclipse.com and I tried to use @DeclareParents to achieve the above functionality. However, I was getting a compiler error from AspectJ, which had to do with generics. It's as if the @DeclareParents annotation did not expect the generics to be used...
Thank you.
Upvotes: 4
Views: 1907
Reputation: 28737
I'd recommend that you use code style aspectj to solve this rather than annotation style.
This could be done simply by having an aspect like this:
aspect CloningServiceAspect {
declare parents : PersonService extends DefaultCloningServiceImpl<Object>;
}
To make this more general and attached to an annotation, you can do something like this:
aspect CloningServiceAspect {
declare parents : (@CloningService *) extends DefaultCloningServiceImpl<Object>;
}
And if you wanted to package this up into a standalone jar, just make sure to add all code that you want to weave adds this jar to its aspect path (if using compile-time weaving).
Upvotes: 2
Reputation: 1009
I found the solution! It involves using the @DeclareMixin annotation from AspectJ to mix the default implementation of the clone() method:
@Aspect
public class CloningServiceAspect {
@DeclareMixin(value = "(@CloningService *)")
public static CloningService<?> createImplementation() {
return new DefaultCloningServiceImpl<Object>();
}
}
And then my service is annotated with @CloningService instead of implementing the interface:
@CloningService
public class PersonService {
// no code
}
Upvotes: 1