AspectJ ITD: implementation of a universal interface

I want my class to implement an interface, but I want to provide method implementation using ITD in one aspect. Is it possible?

Interface:

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

The default implementation is:

 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 PersonService class will declare that it implements the CloningService interface, but the actual implementation of the methods will be provided in DefaultCloningServiceImpl, and the aspect will introduce them to the PersonService.

I followed the example on Eclipse.com and I tried using @DeclareParents to achieve the above functionality. However, I was getting a compiler error from AspectJ that was related to generics. As if the @DeclareParents annotation did not expect the use of generics ...

Thanks.

+4
source share
2 answers

I would recommend you use an aspect of the stylej type to solve this, and not an annotation style.

This can be done simply by having this aspect:

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

To make this more general and anchored to the annotation, you can do something like this:

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

And if you want to pack this into a stand-alone jar, just make sure you add all the code you want to bind, add that jar to your path to the aspect (if you use compilation in time).

+2
source

I have found a solution! It includes using AspectJ's @DeclareMixin annotation to mix the default clone () method implementation:

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

And then my service is annotated using @CloningService instead of implementing the interface:

 @CloningService public class PersonService { // no code } 
+1
source

Source: https://habr.com/ru/post/1399820/


All Articles