【问题标题】:Spring AOP - Access to Repositories autowired field by reflectionSpring AOP - 通过反射访问存储库自动装配字段
【发布时间】:2018-12-31 18:04:54
【问题描述】:

这是第一次在 AspectJ 内部,我可能需要访问存储库的本地私有自动装配字段,以便在 >exactly

我创建了一个切入点,专注于每个 @Repository 注释类的每个方法。当切入点触发时,我会得到当前类实例,我想从中获取 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”(使用调试器验证)。

我关注了How to read the value of a private field from a different class in Java?

我错过了什么? |是否可以? |有什么不同的方法吗?

【问题讨论】:

  • 自动装配发生在所有 bean 都被实例化之后,因此看起来您的代码在此之前运行。什么是你需要做的,而你不能通过配置做的事情?
  • @grimi 试试这个方法stackoverflow.com/questions/7819410/…
  • @Paul 谢谢你的回复!我需要操纵“bean”属性(调用一个全局更改其状态的函数)
  • @springbootlearner 我的英雄!我会尽快在下面发布我的解决方案。谢谢!
  • @grimi 很高兴知道它的工作原理。

标签: java spring aspectj spring-aop


【解决方案1】:

@springbootlearner 建议使用这种方法access class variable in aspect class

我所要做的就是将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();
           }
       }
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-22
    • 2017-03-28
    • 2019-02-28
    • 1970-01-01
    • 2015-07-08
    相关资源
    最近更新 更多