Spring @Uso autorizado

218

Quais são os prós e os contras de usar o @Autowired em uma classe que será conectada pelo Spring?

Só para esclarecer, estou falando especificamente sobre a anotação @Autowired , não sobre a fiação automática em XML.

Provavelmente eu simplesmente não entendo, mas para mim isso quase parece um antipadrão - suas classes começam a perceber que estão ligadas a uma estrutura de DI, em vez de apenas serem POJOs. Talvez eu seja um glutão por punição, mas eu gosto de ter a configuração XML externa para beans e gosto de ter ligações explícitas, para que eu saiba exatamente o que está conectado onde.

Andy White
fonte
4
Também estou interessado neste assunto - configurar seu aplicativo MVC por meio de anotações em vez de XML parece levar a muitas pesquisas sobre "qual classe está mapeada para este URL?" "quem está lidando com isso?" Eu gosto de ter uma única fonte de configuração
matt b
6
o termo "@Autowiring" parece enganoso aqui. Como você também pode fazer a fiação automática com a configuração XML, a pergunta original deve ser reformulada como "Prós e contras do uso de anotações do Spring". A resposta fornecida se concentra mais nos aspectos da fiação automática e menos nos aspectos do uso de anotações.
Neeme Praks 11/03/09
Possível duplicata do Understanding Spring @Autowired use
tkruse

Respostas:

253

Durante muito tempo, acreditei que havia um valor em ter uma "configuração centralizada e declarativa", como os arquivos xml que todos costumávamos usar. Então percebi que a maioria das coisas nos arquivos não era de configuração - nunca foi alterada em lugar algum após o desenvolvimento. Então percebi que "centralizado" só tem valor em sistemas muito pequenos - somente em sistemas pequenos você poderá criar um arquivo de configuração como um todo . E qual é realmente o valor de entender a fiação como um todo, quando as mesmas "ligações" são duplicadas principalmente por dependências no código? Portanto, a única coisa que guardei são os metadados (anotações), que ainda são meio declarativos. Eles nunca mudam em tempo de execução e nunca dados de "configuração" que alguém alterará em tempo real - então eu acho que mantê-lo no código é bom.

Uso a fiação automática completa o máximo possível. Eu amo isso. Não voltarei à primavera à moda antiga, a menos que seja ameaçado à mão armada. Minhas razões para preferir totalmente @Autowiredmudaram ao longo do tempo.

No momento, acho que o motivo mais importante para usar a fiação automática é que há menos uma abstração em seu sistema para acompanhar. O "nome do bean" desapareceu efetivamente. Acontece que o nome do bean só existe por causa do xml. Portanto, uma camada completa de indireções abstratas (onde você colocaria o nome do feijão "foo" na barra de feijão)) desapareceu. Agora, conecto a interface "Foo" diretamente ao meu bean e a implementação é escolhida pelo perfil de tempo de execução. Isso me permite trabalhar com código ao rastrear dependências e implementações. Quando vejo uma dependência com conexão automática no meu código, basta pressionar a tecla "ir para implementação" no meu IDE e a lista de implementações conhecidas é exibida. Na maioria dos casos, há apenas uma implementação e eu vou direto para a classe. Lata' que implementação está sendo usada (afirmo que o oposto está mais próximo da verdade com a fiação xml - engraçado como sua perspectiva muda!)

Agora você pode dizer que é apenas uma camada muito simples, mas cada camada de abstração que adicionamos aos nossos sistemas aumenta a complexidade. Eu realmente não acho que o xml tenha agregado algum valor real a qualquer sistema com o qual trabalhei.

A maioria dos sistemas com os quais trabalho já tem apenas uma configuração do ambiente de tempo de execução da produção. Pode haver outras configurações para teste e assim por diante.

Eu diria que a fiação automática completa é o rubi nos trilhos da primavera: ela abraça a noção de que há um padrão de uso normal e comum que a maioria dos casos de uso segue. Com a configuração XML, você permite muito uso de configuração consistente / inconsistente que pode / não ser pretendido. Eu já vi tantas configurações xml exageradas com inconsistências - elas são refatoradas junto com o código? Pensei que não. Essas variações existem por um motivo? Geralmente não.

Mal usamos qualificadores em nossa configuração e encontramos outras maneiras de resolver essas situações. Essa é uma clara "desvantagem" que encontramos: mudamos um pouco a maneira como codificamos para torná-la mais suave com a fiação automática: um repositório de clientes não implementa mais a Repository<Customer>interface genérica , mas fazemos uma interface CustomerRepositoryque se estende Repository<Customer>. Às vezes, há também um truque ou dois no que diz respeito à subclassificação. Mas geralmente apenas nos aponta na direção de uma digitação mais forte, o que acho quase sempre uma solução melhor.

Mas sim, você está vinculando-se a um estilo particular de DI, principalmente a primavera. Nós nem sequer criamos setters públicos para dependências (para que você possa argumentar que estamos com +1 no departamento de encapsulamento / ocultação de informações) Ainda temos alguns xml em nosso sistema, mas o xml basicamente contém apenas as anomalias. A instalação automática completa integra-se perfeitamente ao xml.

A única coisa de que precisamos agora é que o @Component, @Autowirede o restante, seja incluído em um JSR (como o JSR-250 ), para que não tenhamos que amarrar a mola. É assim que as coisas acontecem no passado (as coisas vêm java.util.concurrentà mente), então eu não ficaria totalmente surpreso se isso acontecesse novamente.

krosenvold
fonte
5
O javax.annotation / javax.inject é suportado pelo spring, portanto você não precisa ter a dependência do código no spring.
Michael Wiles
26

Para mim, aqui está o que eu gosto / o que não gosto na Spring e na fiação automática.

Prós:

  • A fiação automática elimina a configuração XML desagradável.
  • Muito mais fácil de usar anotações, o que permite injetar diretamente usando campos, métodos setter ou construtores. Também permite que você anote e 'qualifique' seus grãos injetados.

Contras:

  • O uso de cabeamento automático e anotações o torna dependente das bibliotecas do Spring, onde, como na configuração XML, você pode optar por executar com ou sem o Spring. Como você disse, você fica vinculado a uma estrutura de DI.
  • Ao mesmo tempo, eu gosto de poder 'qualificar' beans, para mim isso torna o código muito confuso. Se você precisar injetar o mesmo bean em vários lugares, já vi o mesmo nome de string repetido por toda parte. Para mim, isso parece ter potencial para erros.

Comecei a usar a fiação automática quase exclusivamente no trabalho, porque dependemos muito da integração do Spring de qualquer maneira que o problema da dependência seja discutível. Eu trabalhei em um projeto Spring MVC que usava extensivamente a fiação automática e era um pouco difícil de entender.

Eu acho que a fiação automática é um gosto adquirido, uma vez que você se acostuma, percebe o quão poderoso, fácil e muito menos dor de cabeça é trabalhar do que a configuração XML.

Jared Knipp
fonte
3
configuração XML recebe muito menos desagradável se você usar o livre SpringSource Tool Suite, que apresenta autocompletar, feijão gráficos etc
Sean Patrick Floyd
Eu concordo totalmente com você no fato de a fiação automática ficar confusa e dependente das bibliotecas da primavera! Eu nunca usei a configuração XML e estou pensando que talvez devesse seguir esse caminho?
James111
15

Estamos mudando do @Autowire de volta para a configuração XML em nosso grande projeto. O problema é muito baixo desempenho de inicialização. O scanner de fiação automática carrega todas as classes do caminho de classe de pesquisa de fiação automática, portanto, muitas classes são carregadas ansiosamente durante a inicialização do Spring.

Masterhard
fonte
1
Descobri que o javaconfig pode até ser uma solução melhor para iniciar contextos parciais, o que é uma grande vitória. Mas você pode combiná-los facilmente usando @ Autowired / @ Inject em construtores (em outras palavras, alterne para injeção de construtor).
Krossenvold # 9/13
6

Houve muito pouca discussão sobre a mudança de ambientes. A maioria dos projetos em que trabalhei foi um problema real para injetar dependências, dependendo do ambiente em que estamos trabalhando. Com a configuração xml, é bastante simples com o Spring EL e não conheço nenhuma solução agradável com anotações. Acabei de descobrir um:

    @Value("#{${env} == "production" ? realService : dummyService}")
    private SomeService service;

Deveria estar funcionando, mas não é uma solução agradável.

BTakacs
fonte
Abri um tópico separado sobre isso e há uma solução com o Spring @Profilese @Configuration: blog.springsource.org/2011/02/14/… Veja também o outro tópico: stackoverflow.com/questions/13490393/…
BTakacs
4

Mudei para @Autowire. Manter a configuração XML em algo que não seja um projeto pequeno tornou-se uma tarefa por si só e a compreensão foi rapidamente degradada.

O IntelliJ fornece um bom suporte (não perfeito) para anotações do Spring.

Paul McKenzie
fonte
3

Minha opinião sobre esse assunto é que, a configuração xml reduz a clareza do código, especialmente em sistemas grandes.

Anotações como @Component tornam as coisas ainda piores. Ele orienta os desenvolvedores a tornarem os objetos mutáveis, pois as dependências não podem mais ser finalizadas, uma vez que os construtores padrão precisam ser fornecidos. As dependências precisam ser injetadas através do setter público ou descontroladas através do @Autowired. [ainda pior, a injeção de dependência é comprometida com classes que instanciam suas dependências, ainda vejo isso no código recém-escrito!]. Por descontrolado, quero dizer, em sistemas grandes, quando várias implementações (ou filhos) do tipo estão disponíveis, fica muito mais complicado entender qual das implementações foi @Autowired, uma complexidade que torna a investigação de bugs muito mais difícil. Isso também significa que, supostamente, você tem um perfil para o ambiente de teste e outro para produção,

Eu permaneço no meio termo onde declaro minhas classes de configuração, (configuração Spring baseada em java usando @Configuration)

Declaro todos os meus beans explicitamente nas classes de configuração. Eu uso apenas @Autowired nas classes de configuração, o objetivo é limitar a dependência do Spring às classes de configuração

A @Configuration reside em um pacote específico, esse é o único local em que a verificação de primavera é executada. (Isso acelera substancialmente a hora de início em grandes projetos)

Esforço-me para tornar todas as minhas classes imutáveis, especialmente o objeto de dados JPA, Hibernate e Spring, bem como muitas bibliotecas de serialização parecem prejudicar isso. Afasto-me de qualquer coisa que me force a fornecer setters ou remova a palavra-chave final da minha declaração de propriedade.

Reduzir as possibilidades de alterar objetos depois que eles são criados, reduz substancialmente os erros no sistema grande, além de reduzir o tempo para encontrar um erro quando ele existe.

Parece também que força o desenvolvedor a projetar melhor a interação entre as diferentes partes do sistema. Problemas e bugs se tornam cada vez mais erros de compilação, reduzindo o tempo perdido e melhorando a produtividade.

Charbel
fonte
1

Aqui estão algumas das experiências dos
profissionais

  • Torna mais fácil a configuração, pois podemos usar a anotação @Autowire
  • Não deseja usar métodos setter, para que a classe fique mais limpa

Contras

  • Acople firmemente ao arquivo xml, mesmo usando o DI
  • Implementação difícil de encontrar (mas se você estiver usando bons IDs, como intellij, pode se livrar disso)

Nas minhas experiências pessoais, não usei tanto a anotação @AutoWire, mas nos casos de teste.

Rajith Delantha
fonte
1

Eu realmente amo escrever com anotações, em vez de XML. De acordo com o manual do Spring e as últimas versões, XML e anotação alcançaram o mesmo resultado.

Esta é a minha lista

Pró:

  • Remova a linha inútil do xml
  • Simplifique a depuração do código: quando você abre uma classe, pode ler o que tem na classe
  • Com um desenvolvimento mais rápido, um projeto com 400 ou mais linhas de XML é legível?

Contras:

  • Não é uma implementação Java padrão, mas é possível alternar para usar @Inject, que é um Java Standard Api, para que o bean permaneça um Pojo
  • Você não pode simplesmente usar em qualquer lugar, conexão db e assim por diante, mas é apenas uma opinião, eu prefiro ter um lugar onde leia toda a configuração.
Luca Preziati
fonte
0

Pelo que entendi, o @Autowired é o melhor para usar, enquanto refiro-me à referência da interface e use suas funções de substituição, mas só acho que o problema é que às vezes é atribuído a nulo no tempo de execução.

Shubham kapoor
fonte