转自:http://www.manongjc.com/detail/9-ltkjdjajrhusqpg.html
记录一个不易被发现的代码问题:原本一个运行正常的项目 , 最近出现一个奇怪的问题 。 在某个 Controller 的方法中 , 使用的 @autowired 注入的 bean 值变成了 null 。诡异的是 , 同样的 bean 在其他 Controller 中 , 甚至在当前 Controller 的其他方法中 , 都一切如常。
经过问题排查,分析原因,发现这些方法在某次 feature 后加入了 aop 切面做日志分析,于是查看相关修改涉及到的出现类似问题的方法修饰符,都是 private 修饰的方法 。
解释一下原因:
Spring 的 aop 机制使用的是 jdk 自身的动态代理机制或者 cglib 的代理机制实现,分别基于接口和子类继承机制实现。
再具体到 spring aop 部分的源码
Method[] methods = clazz.getMethods();
用 JAVA 反射的方式获取也只能拿到 public/protected 方法,所以 private 方法无法被代理 , 最终导致 bean 注入失败。
综上,这其实是个很简单的问题,但是在编码不规范,或者旧项目改造这类场景中会出现而且不容易发现的问题,开发人员往往执念于未对原方法逻辑有任何改动而忽略掉。使用新加入的切面要确认目标方法的修饰符不为 private。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于