代理对象执行私有方法导致注入的属性为null
代码如下:
@Service
public class PerformanceServiceImpl implements IPerformanceService {
private final static Logger logger = LoggerFactory.getLogger(PerformanceServiceImpl.class);
@Resource
PerformanceDao performanceDao;
@Override
@Transactional(rollbackFor = Exception.class)
public void insertTest() throws Exception {
((PerformanceServiceImpl) AopContext.currentProxy()).insertD();
}
private void insertD() throws Exception {
performanceDao.insertData();
}
}
调用PerformanceServiceImpl 的insertTest方法时报错java.lang.NullPointerException。
debug发现在执行insertD方法时,performanceDao是null。
why?
- 在spring为PerformanceServiceImpl生成代理类时,由于insertD是私有方法,将不会被代理(同理,私有方法也会导致事务失效。注:这里用的是cglib动态代理,图中明显看到Enchancer在生成代理类时,private方法会被过滤
![]()
![]()
- 通过java -cp .;%JAVA_HOME%/lib/sa-jdi.jar sun.jvm.hotspot.HSDB启动HotSpot VM调试器生成内存中的代理类,可以验证代理类并没有代理insertD方法
![]()
- 在insertTest调用insertD时,由于insertD方法没有被代理,所以是直接调用代理对象的insertD方法,而代理对象的performanceDao并没有被spring容器注入过
![]()
- 在普通的代理对象执行逻辑中,走完代理对象的逻辑后,最终还会调用切点的逻辑,也就是走被代理对象的被代理方法,被代理对象的performanceDao在spring创建bean的过程中被注入
![]()





浙公网安备 33010602011771号