andei pensando em algumas limitações sérias que o Spring-Annotations poderia trazer no Spring, e, gostaria de discutir um pouco a respeito para entender melhor. Se o Rodrigo Urubatan puder contribuir, já que ele é quem mantém o projeto, seria bastante interessante.
A primeira é sobre o que já comentei num outra thread, mas vou copiá-lo aqui novamente:
E, como todas as informações de wiring ficam dentro do próprio código através de annotations, perde-se a flexibilidade de ter múltiplas configurações (contextos) para cada deploy. Como lidar com isso?
Usando Spring-Annotations, como dizer que os componentes específicos do Spring MVC (Controllers, ViewResolvers, HandlerMapping, etc) deverão ser adicionados no WebApplicationContext, só que no escopo de um DispatcherServlet específico ([servlet-name]-servlet.xml), e não no ROOT? É extremamente importante isolar as informações de wiring desses componentes de um DispatcherServlet de outros DispatcherServlets declarados no web.xml, já que cada módulo pode ter sua configuração específica sem ter a visibilidade dos beans de outros módulos. Isso também garante que os beans dos AplicationContexts do ROOT não irão acessar beans específicos do Spring MVC.
1 ) não tinha visto este comentário em outra thread, mas segue …
Normalmente quando trabalho com o spring, utilizo auto-wire by name, inclusive quando estou trabalhando com o spring-annotation
outra coisa, usar o spring-annotation não te impede de usar o XML quando tu quiser …
e no proprio código do spring, ja tem partes que utilizam um aproach semelhante (ao autoWireByName que costumo utilizar)
como por exemplo:
<tx:annotation-driven/>
esta tag recebe uma propriedade de nome “transactionManager”, ou seja, para ti usar ela, tu tem que ter um bean de nome transactionManager definido …
e se tu der uma olhada nos códigos que escrevo utilizando o spring-annotation, tu vai perceber que nunca uso o @Property, só o autowire
e por ultimo, como eu sempre falo quando vou falar sobre o spring-annotation, a ideia é manter o que é comportamento dentro do código java, e o que é configuração fora …
quando foi a ultima vez, que tu escreveu um objeto de negócio que dependendo do deploy acessava um DAO diferente?
agora o dataSource é sempre diferente, por isto que em todos os exemplos, o dataSource esta definido em um arquivo XML
mas uma outra opção para isto, se tu realmente quiser alterar apenas algumas propriedades de alguns beans, é utilizar um PropertyReplacer do spring (acho que é este o nome, mas é um bean factory post processor usado para alterar o valor de propriedades de qualquer bean carregado …)
2 ) realmente eu não tinha pensado nisto
estava mais focado na utilização dele junto com JSF onde não existem diversos "dispatchers"
então todos os beans carregados por anotações, são carregados no contexto da aplicação
na verdade, eu nunca precisei declarar mais de um dispatcher servlet em aplicação nenhuma
e acho que nem teria como implementar isto, com o carregamento automático dos beans …
mas como se faz isto no webwork? e em JSF? e …
esta é realmente uma limitação, mas não consigo, pelo menos ainda, encarar como um problema …
considerando que estão na mesma aplicação, qual a vantagem de um bean do ROOT application Context não ter acesso a um controller por exemplo?
se isto for realmente necessário, acho que a unica saida ainda considerando o auto-discovery dos beans, é fazer um filtro por nomes de pacotes
[b]PS.: só para constar, a abordagem que esta sendo utilizada no spring-annotation, é a mesma utilizada na especificação de EJB3, pode não ser perfeita, mas não esta tão errada assim
falando nisto, para a proxima versão, quero adicionar suporte as anotações do EJB3 mesmo [/b]
sim, mas a idéia é usar annotation sempre que possível, certo? Caso contrário não faria sentido usá-lo.
Não, o que ocorre com o tx:annotation-driven não tem nada a ver com ‘autowiring’! A propriedade ‘transactionManager’ é apenas um valor default. Se vc olhar o código fonte, irá perceber que usa Conventions.attributeNameToPropertyName(String attributeName), passando como parâmetro ‘transaction-manager’, o que retorna ‘transactionManager’. Além disso, vc pode muito bem especificar uma outra propriedade usando <tx:annotation-driven transaction-manager=‘txManager’>. É apenas uma referencia de um bean que ele precisa e vc não está fazendo nenhuma DI.
Então, essa comparação do tx:annotation-driven do Spring com Spring-Annotations não é válida.
Eu ainda prefiro as vantagens de não usar autowire. Mas, muitas vezes costumo mesclar as duas formas.
E o que é comportamento e configuração pra vc?
Pra mim existe o que é wiring e configuração, sendo que este último eu externalizo (ex.: arquivo properties). Já o primeiro, wiring, que é toda a lógica de amarrar as dependencias do objeto, eu coloco no XML. E colocar informações de wiring dentro de código Java, como o Spring-Annotations faz, no meu ver, quebra totalmente a DI, como já expliquei no último post.
Várias vezes, não somente de DAO, mas de outras dependências. Pense em um produto que pode ser implantado com uma configuração default. Pra cada feature que adiciono nesse produto, que é solicitado pelos clientes, tenho um XML adicional, sobreescrevendo alguns beans da configuração default para fazer a amarração correta das implementações disponíveis na feature solicitada. Veja que quando eu falo de ‘configuração’ estou me referindo no wiring mesmo, e não de simplesmente trocar o IP do LDAP, até porque isso eu costumo externalizar em properties).
Fala sério. =)
Bom, estamos falando do Spring MVC, correto? Eu sei que no Struts isso é conhecido como ‘módulo’.
Isso é extremamente útil no Spring… como já disse no post anterior. Isola os componentes da camada WEB, e permite que cada dispatcher tenha suas configurações que não são visíveis aos outros dispatchers. Posso ter ViewResolvers, HandlerMappings, MultiPartResolver, HandlerExceptionResolver, etc pra cada módulo, sem ter nenhum conflito entre eles.
Nem deve acessar, certo?
É um problema sim… afinal, como eu faço pra criar dois dispatchers, e pra cada WebApplicationContext eu quero declarar um ViewResolver/UrlMapping/ThemeResolver/etc diferente?
Porque limitou mais uma funcionalidade do Spring… (a outra é a questão do DI)
Como assim, que tipo de suporte de EJB? JPA???
A questão é que o uso de Spring-Annotations limita coisas importantes do Spring. Aquilo que o Spring pregou como base de todo seu framework, que é a DI, é substituída por Dependency Lookup.
Bom, de qualquer forma é uma opinião pessoal. Estou querendo pesar as vantagens/desvantagens, quando usar e quando não usar.
nem tudo que é wiring é configuração …
a URL de um controller que tu escreveu para a tua aplicação faz parte do comportamento dele, e não faz sentido nenhum mudar isto, salvo em casos muito raros
que o teu UsuarioLoginService vai usar o dao se usuários, não é configuração, a implementação do dao de usuários pode mudar, mas este serviço sempre vai usar o mesmo dao.
que um método precisa ser executado dentro de uma transação não é configuração, como esta transação vai ser criada é.
e continuo não achando que o Spring-Annotation quebre o DI, ele usa auto-wiring por default apenas isto …
mas os componentes continuam não sabendo de onde vem ou o que implementa as interfaces das quais eles dependem …
se as dependencias mudaram, não faz sentido as antigas continuarem ali …
se tu esta sobre escrevendo alguns beans, não faz sentido os antigos continuarem ali …
então no que tu remover as classes antigas (tirar o jar delas, ja que é um módulo faz sentido estar num jar separado) e colocar o novo, os componentes novos serão carregados e tudo pronto, a diferença é que em vez de trocar um jar, e deixar um monte de classes “lixo” la, tu vai apenas trocar o jar …
isto vai até te ajudar a deixar as coisas mais limpas e organizadas
hehe, eu disse se tu “realmente quiser”, ou seja, tem que ter muita vontade para fazer isto …
por isto eu não citei o struts, citei os outros que não tem isto, ou seja, não faz falta nenhuma
pelo menos na minha opinião …
continuo dizendo que realmente não acho útil, mas cada doido com as suas manias …
não vejo também vantagem em ter multipartresolvers diferentes para modulos diferentes …
view resolvers fazem mais sentido cascateados do que por modulo, pelo menos em todas as situações que precisei até hoje, o melhor seria se fosse possivel configurar as views por controller, mas como não é, elas acabam sendo globais da aplicação mesmo …
quanto aos handlermappings, sempre achei que eles fossem a pior merda que o pessoal do spring fez, tu ter que declarar um controler em 2 ou 3 lugares diferentes para poder fazer funcionar
mas cada um na sua, isto é só a minha opinião …
como comentei acima, não vejo muita utilidade nisto, mas é sim uma limitação …
com o auto discovery dos beans, não tem como fazer isto, a não ser por filtro de pacotes …
pode realmente ter limitado, como disse antes não acho que tenha limitado o DI, mas limitou sim ter mais de um dispatcher, o que na minha opinião não é um problema, mas como eu disse, se isto realmente for necessário, pode ser feito apenas com filtro de pacotes …
não falei em suporte a EJB e JPA, eu disse abordagem …
ou seja, o modelo de programação usando Spring-Annotation é praticamente o mesmo utilizado para programar com EJB3.
e falei que na proxima versão vai suportar as anotações do EJB3, ou seja
se tu anotar um bean com @Stateless ele vai ser carregado como um singleton no contexto do spring e coisas do genero …
desta forma vai ser possivel praticamente usar o spring como um “container EJB3”
com qual arquitetura pode-se fazer um cadastro de nivel médio em 20 minutos?
o meu foco com o spring-annotation é a produtividade e facilidade de manutenção …
adoro o spring-framework …
mas o XML dele é verboso demais, e torna o projeto mais dificil de manter …
a minha ideia é deixar em XML só o que for configuração da aplicação …
e qual dao o meu MBean vai usar, decididamente não é configuração …
nem faz sentido eu ter na minha aplicação dois “usuarioMBean” com implementações diferentes …
ou seja, se eu tiver que colocar um novo, não faz sentido manter o velho …
claro que esta arquitetura vai ter problemas …
todas tem
e claro que ela não é a solução para todos os problemas, pois nenhuma é …
mas a minha ideia principal com ela ela esta atendendo bem …
que é:
facilidade de desenvolvimento
focar mais no código java do que em XML
se usando hibernate - resolver o problema de quando alguem esquece de colocar no mapeamento do hibernate aquela classe pai de outras 3 persistentes que nunca é usada em um select
não ter que escrever 5 linhas de XML para cada controller que eu criar
não precisar mexer no faces-config.xml toda vez que eu adicionar um método novo em um mbean
não precisar mexer no faces-config.xml toda vez que eu criar um mbean novo
não precisar mexer no hibernate.cfg.xml, nem no applicationContext.xml toda vez que eu criar uma classe persistente nova …
não precisar trabalhar dobrado, colocando informações sobre as minhas classes duas vezes, em dois lugares diferentes que vão perder a sincronia em algum momento e me causar problemas no futuro
não ter que dar manutenção em um XML de 2k linhas, nem em 4 de 500 linhas para adicionar um novo dao na aplicação
e nem procurar no meio destas 2k linhas se uma propriedade do meu bean esta configurada corretamente …
mas para isto não quero perder
a facilidade do auto-wiring
controle de transações
possibilidade de colocar o que eu quiser ou precisar no XML do spring
um montede outras coisas que o spring ja tem pronta
quero continar podendo fazer um cadastro simples em 20 minutos, por que me recuso a acreditar que seja normal levar 6 horas como consideravam em uma outra empresa que trabalhei, e nem 3 dias como uma das empresas que presto consultoria.
quero poder olhar para uma classe qualquer e saber exatamente o que ela faz, em vez de ter que olhar para a classe e procurar em 3 ou 4 arquivos XML diferentes, pois cada um deles muda um pouquinho o comportamento desta classe …
lógico, para isto eu perco a documentação que pode ser gerada a artir do XML do spring …
mas eu acredito que o ganho de produtividade compense isto, até por que da forma como tenho trabalhado, a geração automática de um diagrama de classes UML, funciona como documentação de todas as dependencias do código
e por ultimo … quero também agradecer pelas opiniões e criticas ao projeto, pq são as primeiras fora o pessoal que ja esta usando (tem umas 4 empresas usando o spring-annotation ja )
Leia a respeito das diferenças entre Dependency Injection e Dependency Lookup.
Se entender a diferença entre esses dois vai entender melhor o que estou falando.
Entao, eu nem quero entrar nessa discussao, de o que o Spring-Annotations faz de bom pois estariamos perdendo o foco do topico, que eh justamente de falar sobre as limitacoes que eu apontei. Tudo tem sua limitacao sim, mas o fato de ele quebrar a DI pra mim parece ser muito serio, ja que isso faz parte do core do Spring. Mas pra vc entender porque ele “quebra”, tem que entender alguns conceitos de Dependency Injection. Só para vc ter uma idéia, no EJB antigo existe IoC… mas não atraves de DI. Novamente, sugiro que leia o artigo pois ele vai te explicar. O livro de Spring do Rod Johnson é uma boa também para entender.
E sobre outras coisas que estavamos discutindo tambem nao interessa para o foco da discussao… Por exemplo, se ter mais de um dispatcher eh util ou nao pra vc, nao importa… o que importa eh que ele limitou uma funcionalidade que o Spring oferece… e o que vc acha util ou nao eh um gosto seu, somente seu (arquitetos tem experiencias diferentes). Mas, pelo que eu entendi, vc nem se lembrou desse detalhe pra trabalhar com o Spring-Annotations. Entao acho que eh um ponto importante de se considerar.