Já postei um tópico sobre a utilização de um único EJB para a aplicação toda.
Pensei e tive uma ideia e gostaria de ver a opinião de voces.
Não testei e o código tem vários erros, mas é apenas para exemplificar a ideia.
Gostaria de saber quais os problemas que posso ter.
Performance, se eu utilizo a transação do container, etc.
ex:
class GenericEJB implements SessionBean
{
public Object callMethod(String className, String methodName, Object object)
{
Class targetClass = Class.forName(className);
Object target = targetClass.newInstance();
return targetClass.getMethod(methodName,new Class[] { object.getClass }).invoke(target,new Object[] { object });
}
}
class Delegate
{
protected Object callMethod(String className, String methodName, Object object)
{
GenericEJB ejb = ... pega o ejb todo mundo sabe como;
ejb.callMethod(className, methodName, object);
}
}
class FuncionarioDelegate extends Delegate
{
public Funcionario consultarFuncionario(FuncionarioDTO funcionarioDTO)
{
return (Funcionario) callMethod("FuncionarioService", "consultarFuncionario", funcionarioDTO);
}
}
class FuncionarioService
{
public Funcionario consultarFuncionario(FuncionarioDTO funcionarioDTO)
{
// consulta o funcionario
}
}
class Cliente
{
public void chama()
{
FuncionarioDTO fd = new FuncionarioDTO ();
fd.setCodigo(1);
fd.setNome("Maria");
FuncionarioDelegate f = new FuncionarioDelegate();
Funcionario func = f.consultarFuncionario(f);
}
}
Como podem ver é um negócio louco, mas que pode ter fundamento…
Tem fundamento, sim, e a gente ja usou num projeto aqui - mas desse jeito que vc esta fazendo ta muuuuuuito fraquinho. Recomendo dar uma olhada em dynamic proxies
Mas para ter esse proxy aí deve-se informar a classe em tempo de desenvolvimento.
Mas seria interessante informa-la em tempo de execução através de uma string.
Class.forName(classe);
Achei muito elaborado para apenas fazer uma chamada dinamica.
Não vi utilidade nesse código todo.
Não é mais fácil dar invoke no método.
Mas pela sua experiência isso ajudou com a manipulação de EJBs ?
Pois com essa solução teoricamente resolveria esse problema, pois teria um único EJB para toda aplicação.
O deploy seria bem mais fácil.
você anda trabalhando em algum projeto aqui no Rio?
No último projeto Java por onde eu passei, tinhamos uma GenericEJB MUITO similar ao que você propôs.
O deploy realmente era mais simples e quando queríamos adicionar um novo serviço, precisávamos apenas escrever POJOs e acertar a configuração no preferences (que poderia ser XML, .properties, whatever).
O GenericEJB sabia o que chamar a partir dessa configuração.
Acho que há uma certa perda de performance por conta de utilizar reflection. Mas não sei a que ponto essa perda chega a ser significativa.
Como no nosso caso o objetivo do EJB era apenas o de disponibilizar chamadas remotas aos serviços, não nos deixava muito amarrados. Mas acho que se para cada service você tiver requisitos transacionais diferentes, pode começar a complicar a história.
Outro ponto que você tem que prestar atenção é que se você tem apenas 1 GenericEJB deployado que pode atender a N services, você estará utilizando apenas 1 único pool de Sessions. Então a configuração/tuning tem que levar isso em consideração também.
Sim. Era produtivo deployar novos serviços porque o EJB estava pronto. Era apenas uma questão de escrever sua classe de negócios e fazer a configuração necessária.
Imagine que você usa 1 Session para 10 Services. Será apenas 1 EJB deployado que atende a 10 services.
Agora imagine que você recebe 15 requests/segundo em cada um desses services.
O seu pool de EJB tem que dar conta de atender 150 requests/segundo.
Se você tem services com características muito distintas que necessitam de configurações muito diferentes, ter tudo isso em um único pool vai ser um complicador.
Ex.:
Service precisa de transação? Sim ou não?
Qual timeout necessário para cada service?
Isso é uma das minhas dúvidas.
No caso de transação o método invocado pelo reflection participa.
Mas a maior parte das transações seriam controladas pelo banco.
O pool atende apenas uma requisição por vez ?
Eu pensei que o container criasse instancias do sessionbean sob demanda.
Cria sob demanda. Atende a tantas requisições quantos beans você tiver no pool.
O problema é que se cada service possui características diferentes, um trabalho de fine tuning fica muito mais difícil, não acha? Afinal, você possui um EJBGenérico que atende a 10 services com características distintas.
Exato, louds. Essa era a estratégia adotada. A vantagem é ficar livre para configurar a sua maneira. A desvantagem é que você volta a ter que fazer o deploy de N EJBs e manter N deployment descriptors.
Tem que colocar na balança e ver para o seu caso, o que é melhor.
Se precisa de N configurações diferentes não vejo como não usar N artefatos EJBs. Mas como você mesmo falou, isso é para o tunnig da aplicação, se só isso já for suficiente não é de se reclamar.
Mas já seria uma vantagem ou não ?
Vc teria que apenas que usar a mesma classe genericEJB com nomes JNDI diferentes, não criar várias classes identicas.
Isso pode ?
Agora outra dúvida.
O container pode administrar apenas uma instancia porque eu posso invocar um método de uma instancia simultaneamente por várias threads ?
Não é o que o Web container faz com os servlets ?
Não seria o mesmo com os EJB containers ?
[quote=jprogrammer]Mas já seria uma vantagem ou não ?
Vc teria que apenas que usar a mesma classe genericEJB com nomes JNDI diferentes, não criar várias classes identicas.
Isso pode ?[/quote]
Pode tudo. Depende do seu cenário! Se houvesse uma resposta definitiva para tudo, nossa profissão seria moleza e nós não teríamos salários de milhões que temos!
Um container Web como Tomcat tenta administrar no máximo uma instancia de um servlet.
Qualquer requisição para o servlet faz a invocação do método service.
Várias requisições simultaneas podem invocar o service sem problemas.
A mesma coisa não seria com o EJB container ?
Ele administraria as instancias ou a instancia e invocaria o método deste objeto para várias requisições simultaneamente.
Esse negócio de pool me parece mais apropriado com statefull sessions bean.
Pelo que ouvi falar ele cria instancias sob demanda, ou seja, ele tem 10 instancias no pool, pelo que o louds disse , cada instancia atende uma requisição.
Se tiver 15 requisições ele cria mais 5 instancias.
O pool é só para ter uma chache.
É isso ?
No caso do EJB genérico que vcs fizeram (mcampelo) como ficou isso ?
Porque dá na mesma eu ter um EJB só que atende 100 e ter 10 EJB que atendem 10 cada um. Ou não ?
Se for o mesmo EJB com nomes diferentes, deve dar na mesma. A questão que o marco levanto é quando um dos comandos executados pelo seu EJB precisar de tunning diferente. Se ele for mais importante de repente merece um pool a parte do resto, ou então se tiver requisitos transacionais diferentes.