Spring AOP - доступ к репозиториям с автоматическим привязкой поля по отражению - PullRequest
0 голосов
/ 31 декабря 2018

Впервые внутри AspectJ мне может понадобиться доступ к локальному частному автоматическому полю в Repository, чтобы выполнить некоторые операции с> точно <этим экземпляром. </p>

Я создал pointcut, который фокусируетсяна каждый метод каждого @Repository аннотированного класса.Когда срабатывает pointcut, я получаю текущий экземпляр класса, из которого хочу получить поле bean.

Это так:

@Repository
public class MyDao {

    @Autowired
    private MyBean bean;

    public List<Label> getSomething() {
        // does something...
    }
}


@Aspect
@Component
public class MyAspect {

    @Pointcut("within(@org.springframework.stereotype.Repository *)")
    public void repositories() {
    }

    @Before("repositories()")
    public void setDatabase(JoinPoint joinPoint) {
        try {
            Field field = ReflectionUtils.findField(joinPoint.getThis().getClass(), "bean"); // OK since here - joinPoint.getThis().getClass() -> MyDao
            ReflectionUtils.makeAccessible(field); // Still OK
            Object fieldValue = ReflectionUtils.getField(field, joinPoint.getThis());
            System.out.println(fieldValue == null); // true

            // should do some stuff with the "fieldValue"
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

fieldValue всегда null даже если вместо этого я создаю что-то вроде private | public | package String something = "blablabla";.

Я гарантировал, что "bean-компонент" действительно создается при запуске приложения (проверено отладчиком).

Я следовал Как прочитать значение частного поля из другого класса в Java?

Чего мне не хватает?|Является ли это возможным?|Есть ли другие способы?

1 Ответ

0 голосов
/ 01 января 2019

@ springbootlearner предложил такой подход переменная класса доступа в классе аспектов

Все, что мне нужно было сделать, это заменить joinPoint.getThis() на joinPoint.getTarget()

ИОкончательное решение:

@Aspect
@Component
public class MyAspect {

    /**
     *
     */
    @Pointcut("within(@org.springframework.stereotype.Repository *)")
    public void repositories() {
    }

    /**
     * @param joinPoint
     */
    @Before("repositories()")
    public void setDatabase(JoinPoint joinPoint) {
       Object target = joinPoint.getTarget();

       // find the "MyBean" field
       Field myBeanField = Arrays.stream(target.getClass().getDeclaredFields())
            .filter(predicate -> predicate.getType().equals(MyBean.class)).findFirst().orElseGet(null);

       if (myBeanField != null) {
           myBeanField.setAccessible(true);
           try {
              MyBean bean = (MyBean) myBeanField.get(target);// do stuff
           } catch (IllegalAccessException e) {
               e.printStackTrace();
           }
       }
    }

}
...