Usando uma fonte de dados em vários servlets, com injeção de recursos
-
02-01-2020 - |
Pergunta
Eu tenho um javax.sql.DataSource
que eu quero usar em vários servlets.Eu não gosto da idéia de especificar:
@Resource(name="live-connection", lookup="java:/live-connection", description="Live DB Connection")
private DataSource liveDataSource_;
em cada servlet como parece-me que o quadro vai ter de estar olhando para a fonte de dados para cada servlet e se o nome da fonte de dados as alterações, cada servlet vai ter que mudar muito.
A minha ideia é declarar um Singleton EJB que, em seguida, podem ser declaradas em cada servlet:
@Startup
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class DataSources {
@Resource(name="live-connection", lookup="java:/live-connection", description="Live DB Connection")
private DataSource liveDataSource_;
public synchronized Connection getLiveConnection() throws SQLException {
return liveDataSource_.getConnection();
}
}
Esta é uma forma racional de resolver o problema?Eu sinto que é um pouco pesada para algo que eu teria pensado que seria um problema comum.
Solução
Em geral, é ok IMO.Mas por favor, não deixe o feijão de retornar a ligação, mas diretamente a fonte de dados.Alguns AppServers como o WebSphere automaticamente irá fechar a conexão quando o feijão é o contexto à esquerda novamente.
Outra solução seria a utilização de @Resource(nome="myds") em vez de pesquisa.Se todos os seus Servlets em um Aplicativo Web, em seguida, você pode definir um resource-ref com res-ref-name myds em seu web.xml e resolvê-lo para o real de pesquisa apenas o nome do lugar.
Outras dicas
Eu diria que o uso de um EJB apenas por esse motivo, pode ser um pouco pesado demais, como você escreveu.
Primeiro, a maioria dos modernos aplicação, servidores de cache de que a pesquisa de forma a não ser que caro.
Segunda - você pode usar @Resource(nome="myds") como Robert disse que iria usar o mesmo recurso de referência, que pode ser mapeada para o nome JNDI usando o aplicativo do servidor de mapeamento de funções.
Terceiro - você pode usar CDI para web tem apenas o módulo de solução como esta:
Criar classe que mantenha a sua origem de definição de como este:
public class Datasources {
@Produces @Resource(name="jdbc/yourRef", lookup="yourJNDI")
DataSource myDataSource;
}
E, em seguida, usá-lo servlet usando Injetar:
public class MyServlet extends HttpServlet {
@Inject
private DataSource myDs;