![](/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.