![](/img/trans.png)
[英]Spring MVC: Bean property is not readable or has an invalid getter method Does the return type of the getter match the parameter type of the setter
[英]Spring bean creation failed. Can parameter type of the setter be parent of the return type of the getter?
从DBCP2创建数据源bean时,我遇到此异常。 例外是
由以下原因引起:org.springframework.beans.NotWritablePropertyException:Bean类[org.apache.commons.dbcp2.BasicDataSource]的无效属性'connectionInitSqls':Bean属性'connectionInitSqls'是不可写的或具有无效的setter方法。 setter的参数类型是否与getter的返回类型匹配?
这是我的bean配置
<bean id="fileStore_dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
destroy-method="close" lazy-init="true">
<!-- Just that property which causes problem -->
<property name="connectionInitSqls">
<list>
<value>#{filestore.jdbc.connectionInitSql}</value>
</list>
</property>
</bean>
这是BasicDataSource类中connectionInitSqls的设置程序和获取程序代码。 DBCP2的版本是2.1.1
private volatile List<String> connectionInitSqls;
public List<String> getConnectionInitSqls() {
final List<String> result = connectionInitSqls;
if (result == null) {
return Collections.emptyList();
}
return result;
}
public void setConnectionInitSqls(final Collection<String> connectionInitSqls) {
if (connectionInitSqls != null && connectionInitSqls.size() > 0) {
ArrayList<String> newVal = null;
for (final String s : connectionInitSqls) {
if (s != null && s.trim().length() > 0) {
if (newVal == null) {
newVal = new ArrayList<>();
}
newVal.add(s);
}
}
this.connectionInitSqls = newVal;
} else {
this.connectionInitSqls = null;
}
}
您可以看到setter中的参数是Collection,它是List的超级类型。 但是我不知道为什么春天不能实例化bean。 这是Spring问题还是DBCP2代码中的Bug? 我们可以在setter参数中指定父类型的属性吗? 我该如何解决这个问题? 任何帮助,将不胜感激。
尝试${
代替#{
<property name="connectionInitSqls">
<list>
<value>${filestore.jdbc.connectionInitSql}</value>
</list>
</property>
Spring将使用反射来查找setter属性。 因此,由于属性类型(它将从getter方法getConnectionInitSqls中找到),它将使用setConnectionInitSqls和参数列表来查找setter,因此不会找到异常。
现在,异常消息是不言自明的。 请注意,该属性可能根本不存在。 Spring只能与getter和setter一起使用。 它使用getter方法的返回值类型(该方法很容易找到仅带有get且没有arg方法的前缀)来找到合适的setter方法。
Bean属性“ connectionInitSqls”不可写或具有无效的setter方法。 setter的参数类型是否与getter的返回类型匹配 ?
您可以尝试使用MethodInvokingFactoryBean 。
<bean id="fileStore_dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
destroy-method="close" lazy-init="true">
</bean>
<bean id="customInjector"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="fileStore_dataSource" />
<property name="targetMethod">
<value>setConnectionInitSqls</value>
</property>
<property name="arguments">
<list>
<value>#{filestore.jdbc.connectionInitSql}</value>
</list>
</property>
</bean>
替代方式:
我更喜欢这个,因为它是SAFER 。 原因是所有属性都在实例化阶段本身中设置。 然后在豆之间进行接线。 在前一种情况下,它可能易于出错,因为设置connectionInitSqls的时间是不同的,并且可能已经创建了连接(而无需查看BasicDataSource实现的内部)。
public class CustomBasicDataSource extends BasicDataSource{
public void setConnectionInitSqls(List<String> connectionInitSqls) {
super.setConnectionInitSqls(connectionInitSqls);
}
}
用xml中的此类替换
<bean id="fileStore_dataSource"
class="org.company.somepackage.CustomBasicDataSource" destroy-method="close" lazy-init="true">
...<!-- rest remain same-->
</bean>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.