我有一个访问数据库的泽西岛资源。基本上它在资源初始化时打开一个数据库连接。对资源的方法执行查询。
我观察到,当我不使用 @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
...
}
关于代码最佳实践的一些评论也会有所帮助。
与其考虑使资源成为单例,不如更多地关注管理后端、服务类型对象,例如您的ResponseGenerator
类作为单例,显然不应该在每个请求都实例化。
使资源成为单例也是一种管理方式ResponseGenerator
作为单身人士,但这不是唯一或不一定是最好的方式,请参阅访问 Jersey Resource 类中的外部对象 https://stackoverflow.com/questions/7510874/access-external-objects-in-jersey-resource-class and 如何将协作者连接到 Jersey 资源? https://stackoverflow.com/questions/7121445/how-to-wire-in-a-collaborator-into-a-jersey-resource了解将其注入非单例资源的方法。
请注意,您的ResponseGenerator
类在作为单例运行之前需要进行一些工作,无论是注入到每个请求的资源中还是在单例资源中实例化。它不是线程安全的,您将在启动时打开单个连接并跨请求重用它,这是行不通的,您应该使用连接池来完成高效+安全地跨请求重用连接的繁重工作。
关于代码最佳实践的一些评论也会有所帮助。
您会得到更好的回应http://codereview.stackexchange.com http://codereview.stackexchange.com,
但:
ResponseGenerator
对于类来说是一个糟糕的名称(Web 应用程序中的所有内容都是响应生成器)。
不要使用 String 作为服务和对象的返回类型,使用正确的类型对象(例如,听起来你正在返回一个java.util.List
东西)。
不要吞掉 SQLException,将其冒泡以允许 Jersey 在您的资源中生成 5xx 系列响应代码。
使用最终成员变量。
您的日志对象应该是静态的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)