Когда использовать @Singleton в ресурсе Джерси

У меня есть ресурс Джерси тот доступ база данных. В основном это открывает соединение с базой данных в инициализации ресурса. Выполняет запросы на методах ресурса.

Я заметил, что, когда я не использую @Singleton, база данных открыта в каждом запросе. И мы знаем, что открытие соединения является действительно дорогим правом?

Таким образом, мой вопрос, я должен указать, что ресурс является одиночным элементом, или действительно лучше сохранить его в на запрос особенно, когда ресурс соединяется с базой данных?

Мой код ресурса похож на это:

//Use @Singleton here or not?
@Path(/myservice/)
public class MyResource {

    private ResponseGenerator responser;
    private Log logger = LogFactory.getLog(MyResource.class);

    public MyResource() {
        responser = new ResponseGenerator();
    }

    @GET
    @Path("/clients")
    public String getClients() {

        logger.info("GETTING LIST OF CLIENTS");

        return responser.returnClients();
    }

    ...
    // some more methods
    ...

}

И я соединяюсь с базой данных с помощью кода, подобного этому:

public class ResponseGenerator {
    private Connection conn;
    private PreparedStatement prepStmt;
    private ResultSet rs;

    public ResponseGenerator(){
        Class.forName("org.h2.Driver");
        conn = DriverManager.getConnection("jdbc:h2:testdb");
    }

    public String returnClients(){
        String result;
        try{
           prepStmt = conn.prepareStatement("SELECT * FROM hosts");

           rs = prepStmt.executeQuery();

           ...
           //do some processing here
           ...
        } catch (SQLException se){
            logger.warn("Some message");
        } finally {
            rs.close();
            prepStmt.close();
            // should I also close the connection here (in every method) if I stick to per request
            // and add getting of connection at the start of every method
            // conn.close();
        }

        return result
    }

    ...
    // some more methods
    ...

}

Некоторые комментарии к лучшим практикам для кода также будут полезны.

10
задан dexter 1 May 2010 в 09:05
поделиться

1 ответ

Лучше всего использовать фреймворк наподобие Spring с Jersey, который я описал в аналогичном сообщении . Единственное отличие состоит в том, что вместо внедрения служебного компонента вы должны внедрить объединенный источник данных, и это можно легко настроить с помощью c3p0 .

Пример applicationContext.xml, обратите внимание, что для параметра «scope» задано значение prototype, что эквивалентно синглтону на языке Spring.

<bean id="pooledDataSource" scope="prototype" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="jdbcUrl" value="${jpa.url}" />
    <property name="user" value="${jpa.username}" />
    <property name="password" value="${jpa.password}" />
    <property name="initialPoolSize" value="1" />
    <property name="minPoolSize" value="1" />
    <property name="maxPoolSize" value="3" />
    <property name="idleConnectionTestPeriod" value="500" />
    <property name="acquireIncrement" value="1" />
    <property name="maxStatements" value="50" />
    <property name="numHelperThreads" value="1" />
</bean>

В MyResource.java вы просто добавляете следующее, и Spring вставляет его соответствующим образом.

private DataSource pooledDataSource;
public void setPooledDataSource(DataSource pooledDataSource) {
    this.pooledDataSource = pooledDataSource;
}

Затем вы можете изменить свой ResponseGenerator, чтобы он принимал DataSource и использовал его для запроса базы данных.

-4
ответ дан 4 December 2019 в 05:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: