почему моя пользовательская аннотация на интерфейсе не доступна через отражение - PullRequest
0 голосов
/ 14 мая 2019

Я использую Spring Data для доступа к базе данных Mongo в приложении Spring Boot. Я делаю это, расширяя MongoRepository.

@CrudPublishingRepository
public interface ProfileRepository extends MongoRepository<Profile, String> {

    Optional<Profile> findByUserName(String userName);

    @Query("{'products.contracts.contractId': ?0}")
    List<Profile> findByContractId(String contractId);
}

Для некоторых из моих репозиториев (включая вышеуказанный ProfileRepository) мне нужно выполнять некоторые действия каждый раз, когда выполняется действие сохранения или удаления, поэтому я создал аннотацию @CrudPublishingRepository.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface CrudPublishingRepository {}

Я использовал Spring AOP для перехвата всех методов сохранения и удаления в CrudRepository Spring со следующими советами:

@AfterReturning("execution(public * delete(..)) && this(org.springframework.data.repository.CrudRepository)")
public void onDeleteExecuted(JoinPoint pjp) {
    onDelete(pjp);
}

@AfterReturning("execution(public * deleteById(..)) && this(org.springframework.data.repository.CrudRepository)")
public void onDeleteByIdExecuted(JoinPoint pjp) {
    onDeleteById(pjp);
}

@AfterReturning("execution(public * deleteAll(..)) && this(org.springframework.data.repository.CrudRepository)")
public void onDeleteAllExecuted(JoinPoint pjp) {
    onDeleteAll(pjp);
}

@Around(value = "execution(public * save(..)) && this(org.springframework.data.repository.CrudRepository)")
public Object onSaveExecuted(ProceedingJoinPoint pjp) throws Throwable {
    return onSave(pjp);
}

метод onSave выглядит следующим образом:

private Object onSave(ProceedingJoinPoint pjp) throws Throwable {
    System.out.println(getTopicName(pjp));
    try {
        Object result = pjp.proceed();
        return result;
    } catch (Throwable t) {
        throw t;
    }
}

И, наконец, функция getTopicName (JoinPoint pjp), в которой проблема:

private Optional<String> getTopicName(JoinPoint pjp) {
    Class clazz = pjp.getTarget().getClass();
    while (clazz != null) {
        for (Class i : pjp.getTarget().getClass().getInterfaces()) {
            if (i.getAnnotation(CrudPublishingRepository.class) != null) {
                return Optional.of("found it!");
            }
        }
        clazz = clazz.getSuperclass();
    }
    return Optional.empty();
}

Очевидно, что реализация еще не закончена, но я ожидаю, что она вернет Optional.of («нашел!»), Но это не так.

Когда я отлаживаю, я вижу, что ProfileRepository, как и ожидалось, является одним из интерфейсов, но getAnnotations () возвращает пустой массив.

Может кто-нибудь предложить мне решение или объяснение, почему это не работает?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...