带有静态setter函数的java bean

时间:2011-06-22 09:19:36

标签: java spring tomcat javabeans web.xml

我有一个在tomcat 6上执行的Web应用程序。

我有一个MysqlDb类,它使用Spring JDBC中的BasicDataSource。

到目前为止,我在web.xml中使用了以下bean配置:

<bean id="MysqlDb" class="com.xpogames.gamesisland.mysql.MysqlDb">
    <property name="idDataSource" ref="idDataSource"/>
 </bean>

我有以下setter函数:

  public void setidDataSource(BasicDataSource ds) {
    this._dataSource=(DataSource)ds;
    this._simpleJdbcTemplate = new SimpleJdbcTemplate(_dataSource);
    this._jdbcTemplate = new JdbcTemplate(_dataSource);
 }

我想将我的类转换为使用静态函数,因此我创建了一个空的私有构造函数,因此调用者不会显式地实例化该类。

除此之外我将setidDataSource函数更改为静态函数,但是当我尝试这样做时,我收到以下错误:

  

设置属性值时出错;嵌套异常是org.springframework.beans.NotWritablePropertyException:bean类的无效属性'idDataSource'[com.xpogames.gamesisland.mysql.MysqlDb]:Bean属性'idDataSource'不可写或具有无效的setter方法。 setter的参数类型是否与getter的返回类型匹配?

有没有办法在web.xml中解决此问题,或者我是否需要手动处理 获取ServletContext

ServletContext servletContext = this.getServletContext();
this._context = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);

并从那里获取bean,然后从web.xml

中删除我在此处打印的行

4 个答案:

答案 0 :(得分:3)

首先,您已声明了setter setidDataSource。它应该是setIdDataSource。财产的第一个字母必须是单词set之后的大写字母。

此外,setter方法不能是静态的,而是实例方法。

答案 1 :(得分:2)

Spring-beans默认是单例,只要您使用上下文中的bean,就不需要将您的类实现为单例。 对你的问题最简单的回答是在上下文中设置数据源后从上下文中获取bean,但我认为你想远离上下文。

答案 2 :(得分:2)

类的静态setter当然是可能的(它们只为所有实例设置静态属性),但在IoC模式(在spring中使用)中,bean是实例,术语“bean的属性”总是表示“属性”类的实例“ - 将其视为给定IoC实现的限制。

答案 3 :(得分:0)

我知道我的实施想法很糟糕。我仍然需要一个构造函数,因此构建一个具有静态函数和静态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>

这里创建一个MysqlDb bean并将其配置为使用getInstance() init方法(如果是MysqlDb Class)。我确保在mysqlDb类中有一个setidDataSource()函数,以便正确设置数据源。

<bean id="web.handler" class="com.xpogames.gamesisland.Application">
    <property name="MysqlDb" ref="MysqlDb"/>
</bean>

在这里,我创建了我的应用程序的主bean,并确保从bean配置中设置MysqlDb类的函数setMysqlDb。

到目前为止,mysqlDb充当singelton类,因为它的构造函数受到保护,它只创建一次实例:

public static MysqlDb getInstance() {
    if (instance == null) {
        instance = new MysqlDb();
    }
    return instance;
}

我遇到的问题是,在我使用getInstance()时,在我的应用程序的其他部分,将出现MysqlDb类以及使用setidDataSource设置null的所有变量。

所以解决这个问题我在mysqlDb中创建了另一个名为setInstance的函数:

public static 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);
}

所以这个配置有效。它显然不是推荐的或最佳的解决方案!但在我提出更好的解决方案之前,似乎需要进一步阅读和学习。