Java-бин с функцией статического сеттера - PullRequest
2 голосов
/ 22 июня 2011

У меня есть веб-приложение, которое выполняется на Tomcat 6.

У меня есть класс MysqlDb, который использует BasicDataSource из весеннего JDBC.

До сих пор я использовал следующую конфигурацию bean-компонента в web.xml:

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

и у меня была следующая функция установки:

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

Я хочу преобразовать свой класс для использования статических функций, поэтому я создал пустой закрытый конструктор, чтобы класс не был явным образом создан вызывающими.

Кроме того, я изменил функцию setidDataSource на статическую функцию, но когда я пытаюсь это сделать, я получаю следующую ошибку:

Ошибка установки значений свойств; вложенным исключением является org.springframework.beans.NotWritablePropertyException: недопустимое свойство 'idDataSource' класса бина [com.xpogames.gamesisland.mysql.MysqlDb]: свойство бина 'idDataSource' недоступно для записи или имеет недопустимый метод установки. Соответствует ли тип параметра установщика возвращаемому типу получателя?

Есть ли способ решить эту проблему в web.xml или мне нужно вручную получить ServletContext

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

и получите оттуда боб и просто удалите строки, которые я напечатал здесь из web.xml?

Ответы [ 4 ]

3 голосов
/ 22 июня 2011

Например, вы объявили сеттер setidDataSource.Это должно быть setIdDataSource.Первая буква свойства должна быть заглавной буквой после слова set.

. Кроме того, метод установки должен быть не статическим, а методом экземпляра.

2 голосов
/ 22 июня 2011

Статические установщики для класса, конечно, возможны (они просто устанавливают статическое свойство для всех экземпляров), но в шаблоне IoC (который используется весной), bean является экземпляром, а термин «свойство bean» всегда означает «свойство экземпляра класса "- рассматривайте это как ограничение данной реализации IoC.

2 голосов
/ 22 июня 2011

Spring-бины по умолчанию являются одиночными, вам не нужно реализовывать свой класс как одиночный, если вы используете бин из контекста. Простейший ответ на ваш вопрос - получить бин из контекста после установки источника данных в этом контексте, но я подумал, что вы хотите держаться подальше от контекста.

0 голосов
/ 22 июня 2011

Я понимаю, знаю, что у меня была плохая идея реализации.Мне все еще нужен конструктор, поэтому создание класса со статическими функциями и статическим init - плохая идея, и попытка выполнить статический установщик из bean-компонента не логична и невозможна.

Вместо этого я изменил класс накласс синглтона, так что я смогу использовать его где угодно в моем приложении, и он будет создан только один раз.

спасибо за всю информацию.

update

Iдо сих пор не знаю, если это хороший метод, но, по крайней мере, он работает.

в моем 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-компонент MysqlDb и настраивает его для использования метода getInstance() init, если MysqlDb Class.я удостоверился, что у меня есть функция setidDataSource () в классе mysqlDb для правильной установки источника данных.

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

Здесь я создаю основной компонент моего приложения, и я удостоверился, что у меня есть функция setMysqlDb длякласс MysqlDb, который должен быть установлен из конфигурации bean-компонента.

Пока что mysqlDb действует как класс singelton, потому что его конструктор защищен и создает экземпляр только один раз:Я сталкивался с тем, что в других частях моего приложения всякий раз, когда я использовал getInstance (), появлялся класс MysqlDb и все переменные, которые были установлены с помощью setidDataSource где null.

, чтобы решить эту проблему, я создал еще одну функцию с именем setInstance в mysqlDb:

public static void setInstance (MysqlDb db) {instance = 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);
}

, так что эта конфигурация работает.это явно не рекомендуемое или лучшее решение!но мне кажется, что мне нужно больше читать и учиться, прежде чем я найду лучшее решение.

...