Reputation: 1302
I'm looking to get the Spring Data Repository interface or the bean calling void delete(id)
using AspectJ, the problem with that function is there is no argument or return type to guess the bean, is there any idea how to get the calling bean or the interface name from AspectJ ProceedingJoinPoint.
this is my actual code:
@Pointcut("execution(public * org.springframework.data.repository.Repository+.save(..)) || execution(public * org.springframework.data.repository.Repository+.delete(..)) && target(repository)")
public void publicNonVoidRepositoryMethod(CrudRepository repository) {
}
@Around("publicNonVoidRepositoryMethod(CrudRepository repository)")
public Object publicNonVoidRepositoryMethod(ProceedingJoinPoint pjp , CrudRepository repository) throws Throwable {
.......
}
Upvotes: 0
Views: 1253
Reputation: 2273
This is an old question but someone might find this helpful.
I'm using reflection to get to the bottom of the entity type in the latter scenario. Note: all my entities are implementing Identifiable
interface to allow easy access to getId()
:
@Pointcut("execution(* org.springframework.data.repository.*.delete(..)) && args(entity)")
public void repoDelete(Object entity) {}
@Around(value="repoDelete(entity)",argNames="entity")
public void onDelete(ProceedingJoinPoint pjp, Object entity) throws Throwable{
String invoker = null; //this will become the type name
Long entityId = 0L;
if (entity.getClass().getName().equals("java.lang.Long")){
entityId = (Long)entity;
REFLECT: {
// this returns a list of JPA repository-related interfaces
Class[] interfaces = jp.getTarget().getClass().getInterfaces();
for (Class iface: interfaces) {
// one of them is your JPA repository
if (iface.getName().startsWith("YOUR REPO PACKAGE")){
// the entity type can be accessed via generics
ParameterizedType pType = (ParameterizedType) iface.getGenericInterfaces()[0];
// this list contains two values - the entity type and the identifier type
Type[] typeArgs = pType.getActualTypeArguments();
for (Type t: typeArgs) {
if (t.getTypeName().startsWith("YOUR ENTITY PACKAGE")) {
invoker = t.getTypeName();
break REFLECT;
}
}
}
}
}
} else {
invoker = entity.getClass().getName();
if (entity instanceof Identifiable) entityId = (Long) ((Identifiable) entity).getId();
}
// do whatever you need ...
pjp.proceed();
}
Upvotes: 1
Reputation: 463
You can add target parameter to get your repository that has been called:
@Aspect
@Component
public class SampleAspect {
// Apply to all repositories in package repositories
@After("execution(* repositories.*.delete(*)) && target(repository) && args(id)")
public void afterEntityDelete(CrudRepository repository, Object id) {
...
}
}
Upvotes: 1