You need to enable JavaScript to run this app. Spring注入SakilaDao触发NotWritablePropertyException报错排查
优惠活动
大模型
产品
解决方案
定价
更多

Spring注入SakilaDao触发NotWritablePropertyException报错排查

根因定位

报错触发的核心逻辑是Spring的属性匹配规则与配置/代码定义不匹配:

  • Spring在通过XML配置完成Setter注入时,完全不直接读取类的私有字段,而是严格遵循JavaBeans规范,通过类中公共setter方法的命名推导可注入的属性名
  • 推导规则:如果类中存在方法签名为void setXxx(对应类型 参数)的公共方法,则该类存在可写属性xxx(注意首字母自动小写)
  • 当前不匹配点:
    1. 你的SakilaManagerImpl类中定义的setter方法是public void setDao(SakilaDaoImpl dao),按照规则推导,类的可写属性名是dao
    2. 你在applicationContext.xml中配置的property名称是SakilaDao,Spring会按这个名称查找对应的setSakilaDao()方法,类中不存在该方法,因此抛出NotWritablePropertyException
  • 你之前把字段类型从实现类换成接口类型不生效,是因为问题根源从来不是参数类型,而是property名称和setter方法名完全对不上
修复方案(二选一)

方案1:匹配现有类方法,修改XML配置(改动最小)

直接修改applicationContext.xml中manager bean的property名称,和类中现有setter对应:

<bean id="manager" class="com.java.Training.managerImpl.SakilaManagerImpl">
    <!-- 原name="SakilaDao" 改为name="dao" -->
    <property name="dao" ref="dao"></property>
</bean>

该方案不受dao字段的声明类型影响,不管你用SakilaDaoImpl还是接口SakilaDao声明属性,只要setter是setDao(),这个配置就生效

方案2:匹配现有XML配置,修改类方法

如果你希望保留XML中SakilaDao的property配置,就需要在SakilaManagerImpl中重命名对应的setter/getter方法:

// 替换原有的getDao()、setDao()方法
public SakilaDao getSakilaDao() {
    return dao;
}

public void setSakilaDao(SakilaDao dao) {
    this.dao = dao;
}

推荐该方案的写法,因为属性类型用接口声明符合依赖倒置原则,更易维护。

注意事项
  • 不要混淆Java字段名和Spring可识别的属性名:哪怕你把类中的私有字段直接命名为SakilaDao,只要没有对应的公共setSakilaDao()方法,Spring依然无法识别该属性,会抛出完全相同的报错
  • XML中的property名称尽量遵循Java编码规范用小写开头,减少大小写拼写不一致导致的匹配错误

内容的提问来源于stack exchange,提问作者Saptarshi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.31 14:15:06