edpipole, me desculpe - me expressei mal ou deixei alguma informação de lado.
Não estou usando EJBs nem WebServices - não fui claro quando mencionei ‘serviços’.
deixa ver se consigo corrigir isso:
O projeto é um plugin pro eclipse, a princípio é client server, com hibernate e o spring pra colar os vários bichinhos, os componentes, e obviamente pra ganhar skills com ioc (ou injeção de dependência, como preferirem). Digo a princípio client server porquê os detalhes de implementação (da forma como planejei) irão ficar a cargo do developer de cada componente.
Tenho uma biblioteca (um jar) com todas minhas interfaces de negócio e tipos simples utilizados pelas mesmas (uma penca de type safe enum).
Só pra exemplificar, nessa biblioteca tenho as interfaces:
ITeamDAO
IProjectDAO
IWPRDAO (WPR = Work Product Review)
ITeamDAO define alguns métodos pra CRUD e usa outras interfaces (todas na mesma biblioteca), tipo:
IMember
IRule
As outras interfaces (as dao) por sua vez tb usam outras interfaces e/ou type safes, mais ou menos como a ITeamDAO acima (puts, óbvio ululante né?).
Beleza, essa biblioteca define o que cada componente deve implementar para atender um determinado serviço (tarefa, assunto, esquema, não sei qual outro susbtantivo usar pra nomear isso). Tá num nível de abstração que considero ótimo pro meu caso (não sou especialista em OO mas não vejo como ser mais abstrato).
Na implementação dos componentes propriamente ditos, por exemplo TeamDAO, sei que devo implementar a interface ITeamDAO e qq classe utilizada pela mesma. Importo a biblioteca de interfaces, implemento e fim. Resta só o registry pro bean factory do spring (applicationContext.xml).
Até aqui está tudo direitinho, estou confuso é na hora de fazer o registry do spring, não estou encontrando uma solução decente pra registrar vários componentes sem amarrar o cliente destes à classe de implementação.
Um pouco de código, acho que vai ficar mais fácil de entender. A classe para registry do componente ProjectDAO:
[code]public final class ProjectDAORegistry {
private static final Logger _log = Logger.getLogger( ProjectDAORegistry.class.getName() );
private static final ApplicationContext _ctx = getApplicationContext();
private static ApplicationContext getApplicationContext() {
ApplicationContext ctx = null;
try {
ctx = new ClassPathXmlApplicationContext( “applicationContext.xml” );
} catch ( final Exception e ) {
_log.error( “application context not found.” );
}
return ctx;
}
public static SessionFactory getSessionFactory() {
return (SessionFactory) _ctx.getBean( “factory”, SessionFactory.class );
}
public static IProjectDAO getProjectDAO() {
return (IProjectDAO) _ctx.getBean( “projectDAO”, ProjectDAO.class );
}
private ProjectDAORegistry() {} // Singleton //
}[/code]
Maravilha né? como manda o figurino (pelo menos a documentação do spring).
Qualquer outro componente que precise desse dao (ProjectManager por exemplo) simplesmente usará algo do tipo:
É exatamente essa linha de código que está me complicando. Ela por sí só já acopla o cliente à classe de implementação. Se eu precisar usar 50 desses compo nentes vou ter de amarrar o cliente (hard coded, como acima) à esses 50 caras.
Ainda nem tenho certeza de quê essa preocupação é pertinente mas fico imaginando que essa linha possa ser facilmente replicada no meu código me fazendo acreditar que seja (se quiser usar um ProjectSuperDAO ao invés do ProjectDAO vou ter de sair procurando isso no meu fonte e ainda terei de recompilar tudo).
A primeira idéia que me veio à cabeça foi mover o registry de cada um dos componentes dao pra biblioteca comum, mas só estou mudando o problema de local (e o registry desses dao está acoplado à implementação).
Pensei então em simplesmente replicar a info do registry desses componentes (os dao) num singleton na biblioteca comum, dentro de um hash. O registry assim ficaria igualzinho ao o do código do ProjectDAORegistry acima só que em vez de retornar o bean apontado no application context ele o armazenaria nesse singleton (GlobalBeans), como segue:
public static void initProjectDAOManager() { // antigo getProjectDAOManager()
GlobalBeans.put( "projectDAO", _ctx.getBean( "projectDAO", ProjectDAO.class ) );
}
O cliente então poderia utilizar o bean apropriado qdo precisasse usando:
Mas isso ainda não resolve o problema visto que esse cliente ainda vai ter de conhecer o registry de cada componente pra poder chamar seu método init correspondente (e tb não dá pra mover isso pra classe comum, a GlobalBeans, pois daí, novamente, ela é que ficaria dependente dos mesmos componentes).
O problema, no final das contas, pode ser resumido mais ou menos assim:
como posso fazer o registry de n componentes sem acoplar fortemente os clientes desses mesmos componentes? A idéia da ioc é essa não?
Alguém aqui já passou pela mesma dificuldade ? (se é que isso é difícil)