spring中XML中Bean property 'dataSource' is not writable or has an invalid setter method.

本文解决了一个关于Spring框架应用上下文初始化失败的问题,并深入分析了配置错误导致的数据源设置不当,最终通过修正配置文件中的数据源名称为正确拼写,成功解决了错误。

错误提示,如下

 

log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personDao' defined in class path resource [applicationContext.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'dataSource' of bean class [demo.spring.jdbc.object.ObjectPersondaoImpl]: Bean property 'dataSource' is not writable or has an invalid setter method. Did you mean 'dateSource'?
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'dataSource' of bean class [demo.spring.jdbc.object.ObjectPersondaoImpl]: Bean property 'dataSource' is not writable or has an invalid setter method. Did you mean 'dateSource'?
 at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:793)
 at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:645)
 at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:78)
 at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:59)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1127)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:862)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:423)
 at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:249)
 at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:155)
 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:246)
 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
 at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:291)
 at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:352)
 at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:122)
 at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:66)
 at Test.main(Test.java:18)

Test.java.18语句:ClassPathXmlApplicationContext cpx=new ClassPathXmlApplicationContext("applicationContext.xml");

解决办法:起初我以为是xml中配置有错误,后来仔细检查整个程序代码,发现原来有一处的dataSource被写成了dateSource。

 

<think>嗯,我现在遇到了Spring框架中的一个问题,Bean创建失败,报错是BeanCreationException,具体原因是NotWritablePropertyException,提示setter和getter不匹配。我需要解决这个问题,但不太清楚具体应该怎么做。让我仔细想一想。 首先,我需要理解这个异常的意思。NotWritablePropertyException通常指的是Spring在尝试注入属性时,找不到对应的setter方法,或者setter方法的类型不匹配。比如,在配置文件中可能指定了一个属性,但对应的bean类中没有正确的setter方法,或者参数类型不符。 那可能是什么情况导致的呢?比如,我有一个Bean类,里面有一个属性叫“userName”,然后在XML配置或者使用@Autowired的时候,Spring会尝试调用setUserName方法。如果这个方法不存在,或者参数类型不对,比如setUserName的参数是String类型,但配置中注入了其他类型,就会报这个错。 接下来,我需要检查哪里出错了。首先,检查异常信息中的具体属性名称,比如例子中的“dataSource”,然后去对应的Bean类里看看是否有对应的setter方法。比如,是否有setDataSource方法,并且参数类型是否匹配。比如,如果属性是DataSource类型,那么setter方法应该是public void setDataSource(DataSource ds),而如果配置中注入的却是字符串,那就会类型不匹配。 另外,还要注意属性名是否正确,比如是否有拼写错误,或者大小写问题。比如,属性名是dataSource,但setter方法写成了setDatasource,这样Spring可能无法识别,因为根据JavaBean规范,setter方法的名字应该是属性名首字母大写后的形式。 还有一种情况是,可能使用了Lombok的@Data或者@Setter注解,自动生成setter方法,但可能因为某些原因(比如版本问题或配置问题)导致生成的setter方法不符合预期,这时候需要检查生成的代码是否正确。 此外,如果是基于注解的配置,比如使用@Autowired进行字段注入,但同时又为该字段定义了setter方法,这时候如果setter方法的参数类型和字段类型不一致,也可能导致问题。不过通常字段注入不需要setter,但如果同时存在,可能需要检查是否冲突。 还有可能是在XML配置中使用了<property name="dataSource" ref="dataSource"/>,但对应的bean类中没有setDataSource方法,或者ref指向的bean类型不匹配。 解决方案的话,首先根据错误信息中的属性名,检查对应的setter方法是否存在,参数类型是否匹配。例如,如果属性是dataSource,对应的setter方法应该是setDataSource,参数类型是DataSource。如果配置中注入的是字符串,而setter需要的是其他类型,就会出错,这时候需要调整注入的值或者类型。 另外,检查是否有拼写错误,比如属性名是否正确,或者在配置中是否写错了名字。比如,把dataSource写成了datasource,而Bean类中的setter是setDataSource,这时候也会出错,因为Spring对大小写敏感。 如果使用Lombok,可能需要检查生成的setter方法是否符合预期,或者手动编写setter方法以确保正确性。 还有一种可能是,属性在Bean类中是只读的,只有getter没有setter,这时候Spring无法注入,需要添加对应的setter方法,或者改为构造函数注入。 总结一下,解决步骤应该是: 1. 查看异常信息中的属性名和类名,定位问题位置。 2. 检查对应的Bean类是否有该属性的正确setter方法(方法名和参数类型)。 3. 检查配置中的注入值是否与setter方法的参数类型匹配。 4. 检查是否有拼写错误或命名规范问题。 5. 如果使用Lombok或其他工具生成代码,检查生成的代码是否正确。 6. 考虑使用构造函数注入或字段注入代替setter注入,避免此类问题。 比如,假设在配置中有一个属性userService,但Bean类中的setter方法是setUserServiceImpl,而参数类型是UserServiceImpl,但配置中注入的是UserService接口类型,这时候可能会因为类型不匹配导致错误,需要调整注入的bean类型或setter方法的参数类型。 另外,还要注意是否在Bean类中同时存在同名的属性和setter方法,但类型不一致,比如属性是List类型,而setter方法参数是Set类型,这也会导致类型不匹配。 总之,解决这个问题的关键在于仔细检查setter方法的存在性、命名正确性以及参数类型的匹配性,同时确保配置中的注入值与这些setter方法的要求一致。</think>### Spring框架中Bean创建失败问题解决方案 #### 问题分析 当Spring抛出`BeanCreationException`并提示`NotWritablePropertyException`时,通常表示**属性注入时存在setter方法缺失或类型不匹配**。常见原因包括: 1. **缺少setter方法**:XML配置或注解中指定的属性没有对应的`setXxx()`方法[^1]。 2. **类型不匹配**:setter方法参数类型与注入值的类型不一致。 3. **命名规范问题**:属性名称与setter方法命名不符合JavaBean规范(如驼峰式命名)。 4. **依赖注入冲突**:同时使用字段注入和setter注入时可能引发歧义。 --- #### 逐步解决方案 1. **定位具体属性** - 从异常信息中提取关键信息,例如: ``` Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'dataSource' of bean class [com.example.MyService]: Bean property 'dataSource' is not writable or has an invalid setter method ``` 此处问题属性为`dataSource`。 2. **检查setter方法** - 确保目标类中包含正确的setter方法: ```java public class MyService { private DataSource dataSource; // 方法名必须为 set + 属性名(首字母大写) public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } } ``` - **注意**:若使用Lombok的`@Setter`注解,需验证生成的代码是否符合预期。 3. **验证类型一致性** - 检查XML配置或注解中的注入值类型是否与setter参数类型匹配: ```xml <!-- 示例:dataSource属性的ref必须指向DataSource类型的Bean --> <property name="dataSource" ref="mysqlDataSource"/> ``` 若`ref="mysqlDataSource"`对应的Bean类型不是`DataSource`或其子类,则会导致类型不匹配。 4. **排查命名问题** - 避免拼写错误(如`dataSource`误写为`datasource`)。 - 遵循驼峰式命名规范,例如属性名`userName`对应`setUserName()`。 5. **替代方案:构造函数注入** - 如果属性为必需依赖,改用构造函数注入可避免setter缺失问题: ```java @Component public class MyService { private final DataSource dataSource; // 通过@Autowired标注构造函数 @Autowired public MyService(DataSource dataSource) { this.dataSource = dataSource; } } ``` --- #### 代码验证示例 假设错误由以下错误配置引起: ```xml <bean id="myService" class="com.example.MyService"> <property name="dataSource" ref="textFile"/> </bean> ``` 而`textFile`是一个`String`类型的Bean,修复方式为: ```xml <!-- 修正:注入正确的DataSource类型Bean --> <property name="dataSource" ref="mysqlDataSource"/> ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值