controller层注入service为null,service使用Transactional注解 导致enhancerbyspringcglib问题

一、问题展现

      项目都正常开发,突然有一天,发现某个同事写的contoller层注入service为null,但是部分controller又是正常的。并且有时候还会存在通过postman调用controller正常注入service,其他系统通过httpClient调用controller不能正常注入service。

二、问题调查

      1、使用postman调用其他的controllerA  发现正常, 并且把同样的service注入到controllerA  正常注入 没有任何问题。

           有个小插曲,中间还在spring-boot启动项上 打印出所有的bean  看看是否有两个对应的controllerW  bean注入   然并没有

             

       ApplicationContext ctx =SpringApplication.run(App.class, args);

        System.out.println("Let's inspect the beans provided by Spring Boot:");
        String[] beanNames = ctx.getBeanDefinitionNames();
        java.util.Arrays.sort(beanNames);
        for (String beanName : beanNames) {
            System.out.println(beanName);
        }

   

      2、比较正常controllerA  与 不正常的controllerW   发现没有什么本质的区别,代码也基本上没有什么变动。 诡异中...

      3、断点  分析 比较发现   不正常的controllerW 有个诡异问题,enhancerbyspringcglib  这时候真相已经隐藏在图中了  只是笨拙的我没有发现问题~@@~

        不正常图1

        

    正常图2

   

    4、区别在哪里  在哪里,  enhancerbyspringcglib    网上搜索关键词   enhancerbyspringcglib 

    得到如下资料 a、https://blog.csdn.net/itrider/article/details/43634941

                           b、http://jinnianshilongnian.iteye.com/blog/1508018

                           c、http://jinnianshilongnian.iteye.com/blog/1508018

                              深入 Spring Boot:排查 @Transactional 引起的 NullPointerException

                           d、http://www.sohu.com/a/216425181_355142     

         5、整理了一下cglib代理 与 jdk动态代理的区别    等  controllerW上注入的service上确实有使用到注解

       @Transactional(rollbackFor = PicaException.class)     以为如获至宝    然并暖用,只能说明是可能一个点  但肯定不     是这个问题引起的      因为controllerA 注入同样的service 没有问题的

        6、 同时把所有的service中使用@Transactional 注解暂时注释掉     问题没有得到解决, 但是发现一个现象  这时候service 注入的方式改变了   如下图

这个现象暂时 不影响正常使用    可以暂时过一下   但   是不是跟controllerW 注入方式一样呢?  很像吧     这时候陷入死胡同  为什么??

     7、陷入死胡同,这时候只能判断这个问题 controllerW的写法有问题,肯定做了什么见不得人的操作, 只能来代码比较 代码比较,询问当事人,  当事人回答,之前哪个日期点的代码是好的,  好好,  那就一点点代码回退,一点点代码比较, 问题终于重现了,  可以正常运行的代码 与 有问题的代码的时间节点    内容差异, 发现controllerW 方法体上用了  private修饰  再看一下其他     都是public     果断重现用public试一下   ok    问题得到解决

    8、查找资料

         a、https://blog.csdn.net/weixin_41633157/article/details/80083636            

原因分析:

容器扫描bean生成代理类的时候,public和protected方法可以被正常代理,而private方法的不会被代理,属性的注入也是在代理类中完成,所以public/protected方法获取的注入属性是完成注入的属性,private方法获取的是未完成注入时的属性,所以是null

   9、问题得到解决   但是走了不少弯路。

三、 总结

    1、解决问题过程中,心态不够好,有点急躁

    2、准确定位搜索关键词     这是个提炼能力的问题点。  如果直接搜索  “controller  方法private   导致注解丢失“ 明显很直接得 到答案

    3、对spring bean注入 理解不到位。

猜你喜欢

转载自blog.csdn.net/sinat_41620463/article/details/82863661
今日推荐