从AspectJ ProceedingJoinPoint获取Spring Bean

时间:2015-06-01 05:41:11

标签: spring spring-boot spring-data aspectj

我希望使用AspectJ获取Spring Data Repository接口或bean调用void delete(id),该函数的问题是没有参数或返回类型来猜测bean,有什么想法吗?如何从AspectJ ProceedingJoinPoint获取调用bean或接口名称。

这是我的实际代码:

@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 {

.......
}

2 个答案:

答案 0 :(得分:1)

您可以添加目标参数以获取已调用的存储库:

DATEPART (wk, 'Jan 1, xxxx') = 1

答案 1 :(得分:1)

这是一个老问题,但有人可能会觉得这很有帮助。

  • 在CrudRepository,PagingAndSortingRepository等上声明所有删除方法的切入点。:
  • 从您的代码调用时,您可以传递实体本身
  • 另一方面,当通过Spring Data REST调用时,使用ID调用delete方法(在本例中为Long)

我在后一种情况下使用反射来到实体类型的底部。注意:我的所有实体都在实施Identifiable界面,以便轻松访问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();
}