具有静态setter函数的javabean
我有一个在Tomcat6上执行的web应用程序 我有一个MysqlDb类,它使用来自SpringJDBC的BasicDataSource 到目前为止,我在具有静态setter函数的javabean,java,spring,tomcat,javabeans,web.xml,Java,Spring,Tomcat,Javabeans,Web.xml,我有一个在Tomcat6上执行的web应用程序 我有一个MysqlDb类,它使用来自SpringJDBC的BasicDataSource 到目前为止,我在web.xml中使用了以下bean配置: <bean id="MysqlDb" class="com.xpogames.gamesisland.mysql.MysqlDb"> <property name="idDataSource" ref="idDataSource"/> </bean> 我想
web.xml
中使用了以下bean配置:
<bean id="MysqlDb" class="com.xpogames.gamesisland.mysql.MysqlDb">
<property name="idDataSource" ref="idDataSource"/>
</bean>
我想将我的类转换为使用静态函数,所以我创建了一个空的私有构造函数,这样类就不会被调用方显式实例化
除此之外,我还将setidDataSource
函数更改为静态函数,但当我尝试这样做时,会出现以下错误:
设置属性值时出错;嵌套异常为org.springframework.beans.NotWritablePropertyException:bean类[com.xpogames.gamesisland.mysql.MysqlDb]的无效属性“idDataSource]:bean属性“idDataSource”不可写或具有无效的setter方法。setter的参数类型与getter的返回类型匹配吗
是否有办法在web.xml中解决此问题,还是需要手动解决
获取ServletContext
ServletContext servletContext = this.getServletContext();
this._context = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
然后从那里获取bean,只需删除我在这里从
web.xml
?打印的行,首先,您声明了settersetidDataSource
。它应该是setIdDataSource
。属性的第一个字母必须是单词set
后的大写字母
另外,setter方法不能是静态的,而必须是实例方法。我知道我的实现想法不好。我仍然需要一个构造函数,所以用静态函数和静态init构建一个类是一个坏主意,并且尝试从bean执行静态setter不是合乎逻辑的,也是不可能的 相反,我将该类更改为单例类,因此我可以在应用程序中的任何位置使用它,并且只构建一次 谢谢你提供的所有信息 更新 我仍然不知道这是否是一个好方法,但至少它是有效的 在我的red-web.xml(将其视为spring applicationContext.xml)中,我有以下内容:
<bean id="MysqlDb" class="com.xpogames.gamesisland.mysql.MysqlDb" init-method="getInstance">
<property name="idDataSource" ref="idDataSource"/>
</bean>
在这里,我创建了应用程序的主bean,并确保从bean配置中为MysqlDb类设置函数setMysqlDb
到目前为止,mysqlDb充当Singleton类,因为它的构造函数受到保护,并且只创建一次实例:
public static MysqlDb getInstance() {
if (instance == null) {
instance = new MysqlDb();
}
return instance;
}
我遇到的问题是,在我的应用程序的其他部分,每当我使用getInstance()时,就会出现MysqlDb类,并且会出现使用setidDataSource wherenull
设置的所有变量
为了解决这个问题,我在mysqlDb中创建了另一个名为setInstance
的函数:
公共静态void setInstance(MysqlDb){
实例=db;
}
这是我的主应用程序中的主要setMysqlDb函数:
public void setMysqlDb(MysqlDb db) {
this._mysqlDb=db;
/* it seems that without forcing a setInstance on the class, whenever other classes
* would try to getInstance(), variables that are supposed to be configured by the bean
* would be empty. this resolves that issue
*/
MysqlDb.setInstance(db);
}
所以这个配置是有效的。这显然不是推荐的或最好的解决方案!但是,在我提出更好的解决方案之前,我似乎需要进一步阅读和学习。SpringBean默认为单例,只要从上下文使用bean,就不需要将类实现为单例。
对于您的问题,最简单的答案是在上下文中设置数据源后从上下文中获取bean,但我认为您希望远离上下文。类的静态设置器当然是可能的(它们只会为所有实例设置静态属性),但在IoC模式(在spring中使用)中,bean是实例,术语“bean的属性”总是指“类实例的属性”——将其视为给定IOC实现的限制。不能使用静态SETTER方法。这是行不通的,它们必须是实例方法。如果没有setter(实例)方法,它就不是bean。基本上,bean是一个实例/对象;静态成员不引用实例,只引用静态数据。因此,您得到了一个没有方法对其进行变异的对象(我不知道您为什么需要静态“setters”,这似乎是矛盾的)。您可能能够说服数据源使用它,这取决于它的检查有多严格,但如果它拒绝合作,我不会反对它?Spring提供了其他创建bean的方法,比如工厂。我不想将指向已构建类的指针粘贴到应用程序的每个部分。我希望能够使用静态方法调用此类中的每个函数
我希望将我的类转换为使用静态函数
-为什么?这是一个非常糟糕的主意。welp它确实适用于小写字母:)我想这取决于我如何配置属性名为web.xml。您的答案是“注释”,而不是答案。您可以尝试让它更“回答”,因为它已经收到了两个“notanswer”标志=),也许使用上下文是一个更好的主意。还在考虑。谢谢你的建议。
public static MysqlDb getInstance() {
if (instance == null) {
instance = new MysqlDb();
}
return instance;
}
public void setMysqlDb(MysqlDb db) {
this._mysqlDb=db;
/* it seems that without forcing a setInstance on the class, whenever other classes
* would try to getInstance(), variables that are supposed to be configured by the bean
* would be empty. this resolves that issue
*/
MysqlDb.setInstance(db);
}