spring中,子类初始化父类属性,父类使用这个属性却是NULL,为什么?

发布于 2022-09-06 02:21:25 字数 3777 浏览 28 评论 0

四个class类似如下

public abstract class DefaultSimpleFirmwareServiceImp implements SimpleFirmwareService {
        private JVMCacheWrap<Map<Integer, List<SimpleFirmware>>> firmwareCache;
        protected abstract SimpleFirmwareRepository getFirmwareRepository();

        protected final JVMCacheWrap<Map<Integer, List<SimpleFirmware>>> getCache() {
                return firmwareCache;
        }

        protected final void initService(String moduleKey, int[] hardwares) {
                firmwareCache = JVMCacheFactory.create(balabala...);
        }

        public abstract void init();
       
        public final void saveFirmware(SimpleFirmware firmware) throws Exception {
                getFirmwareRepository().saveFirmware(firmware);
                getCache().stale();
        }
}

@Component
@Qualifier("goFirmwareService")
public class GoFirmwareServiceImp extends DefaultSimpleFirmwareServiceImp implements GoFirmwareService {

        @Override
        protected SimpleFirmwareRepository getFirmwareRepository() {
                return balabala...;
        }
        @Override
        @PostConstruct
        public void init() {
                initService("go", new int[] { 1 });
        }
}


public abstract class SimpleFirmwareAdminAction extends BaseAction {
        protected abstract SimpleFirmwareService findFirmwareService();

        public String firmware_save() throws Exception {
                findFirmwareService().saveFirmware(getParameterBean(new SimpleFirmware()));
                return NONE;
        }

        balabala...
}

@Controller
public class GoAdminAction extends SimpleFirmwareAdminAction {
        private static final long serialVersionUID = 6955716525662800331L;
        @Autowired
        private GoFirmwareService goFirmwareService;

        @Override
        protected SimpleFirmwareService findFirmwareService() {
                return goFirmwareService;
        }

        balabala...
}

structs 调用 GoAdminActionfirmware_save 的方法,最终调用了DefaultSimpleFirmwareServiceImp.saveFirmware方法,但是getCache()方法返回了NULL,出现了空指针异常
但是initServiceGoFirmwareServiceImp在初始化的时候调用了,firmwareCache的值不应该为空
没有setCache方法,所以不会出现其他地方又置为NULL的情况

应该不是父类属性修饰符的问题
图片描述

DEBUG部分截图

  • GoFirmwareServiceImp.init()调用了DefaultSimpleFirmwareServiceImp.initService()方法

图片描述

  • GoFirmwareServiceImp.init()调用结束

图片描述

  • 向API发送数据,Controller的SimpleFirmwareAdminAction.firmware_save()方法被调用

图片描述

  • SimpleFirmwareAdminAction.firmware_save()方法调用子类的GoAdminAction findFirmwareService()的方法

图片描述

  • 然后findFirmwareService()返回了service,并调用了DefaultSimpleFirmwareServiceImp. saveFirmware()方法,该方法调用了getCache方法,出现了NULL,如图

图片描述

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

软甜啾 2022-09-13 02:21:25

由于cglib代理原因导致的,解决方法是 原来的protected final改为public就OK了,只改修饰符为public不行。

梦罢 2022-09-13 02:21:25

因为这句private JVMCacheWrap<Map<Integer, List<SimpleFirmware>>> firmwareCache;,你使用了private的可见性,而对于private父子类是不会共享的,也就是说父类有一份,子类也有一份,你在初始化的时候是初始化了子类的这个属性,然而到了你使用的时候,getCache方法返回的是父类的cache,所以为空,可以把private换成protected,应该就可以了

空城缀染半城烟沙 2022-09-13 02:21:25

initService()方法里面打印下类的hashcode.
getCache()方法里面也打印下类的hashcode.

System.out.println(this);

看看是不是同一个实例。

眼睛会笑 2022-09-13 02:21:25

谢邀,因为这个代码:

@Override

    @PostConstruct
    public void init() {
            initService("go", new int[] { 1 });
    }

在@Autowired的GoFirmwareService实例化之后执行,所以你在执行init()之前调用getCache()返回空值。

你爱我像她 2022-09-13 02:21:25

父类属性 修饰词 导致的吧

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文