代理对象执行私有方法导致注入的属性为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?

  1. 在spring为PerformanceServiceImpl生成代理类时,由于insertD是私有方法,将不会被代理同理,私有方法也会导致事务失效。注:这里用的是cglib动态代理,图中明显看到Enchancer在生成代理类时,private方法会被过滤

     

     

  2. 通过java -cp .;%JAVA_HOME%/lib/sa-jdi.jar sun.jvm.hotspot.HSDB启动HotSpot VM调试器生成内存中的代理类,可以验证代理类并没有代理insertD方法

  3. 在insertTest调用insertD时,由于insertD方法没有被代理,所以是直接调用代理对象的insertD方法,而代理对象的performanceDao并没有被spring容器注入过

     

  4. 在普通的代理对象执行逻辑中,走完代理对象的逻辑后,最终还会调用切点的逻辑,也就是走被代理对象的被代理方法,被代理对象的performanceDao在spring创建bean的过程中被注入

     

     

posted on 2024-01-23 15:35  zhengbiyu  阅读(105)  评论(0)    收藏  举报