Uso de Spring @Autowired

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

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

Eu provavelmente não entendo, mas para mim isso quase parece um anti-padrão – suas aulas começam a se tornar conscientes de que elas estão ligadas a um framework de DI, ao invés de serem apenas POJOs. Talvez eu seja um comilão por punição, mas eu gosto de ter a configuração XML externa para beans, e eu gosto de ter fiações explícitas, então eu sei exatamente o que está ligado onde.

Por muito tempo acreditei que havia um valor em ter uma “configuração declarativa e centralizada”, como os arquivos xml que todos nós costumávamos usar. Então percebi que a maioria das coisas nos arquivos não era configuração – nunca foi alterada depois do desenvolvimento, nunca. Então percebi que “centralizado” só tem valor em sistemas bem pequenos – somente em sistemas pequenos você conseguirá agregar um arquivo de configuração como um todo . E qual é realmente o valor de entender a fiação como um todo, quando as mesmas “fiações” são praticamente duplicadas por dependencies no código? Então, a única coisa que eu mantenho são metadados (annotations), que ainda são meio declarativos. Eles nunca mudam em tempo de execução e eles nunca são dados de “configuração” que alguém vai mudar na hora – então acho que mantê-lo no código é legal.

Eu uso toda a fiação automática o máximo que posso. Eu amo isso. Eu não vou voltar para a primavera de estilo antigo a menos que ameaçado no ponto da arma. Minhas razões para preferir totalmente o @Autowired mudaram com o tempo.

No momento, acho que a razão mais importante para usar o autowiring é que há menos uma abstração em seu sistema para rastrear. O “nome do bean” foi efetivamente eliminado. Acontece que o nome do bean existe apenas por causa do xml. Assim, uma camada completa de indirecções abstratas (onde você ligaria o bean-name “foo” para o bean “bar”) 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 dependencies e implementações. Quando vejo uma dependência autônoma no meu código, basta pressionar a tecla “ir para a implementação” no meu IDE e surge a lista de implementações conhecidas. Na maioria dos casos, há apenas uma implementação e estou direto para a aula. Não pode ser muito mais simples do que isso, e eu sempre sei exatamente qual implementação está sendo usada (eu afirmo que o oposto está mais próximo da verdade com a fiação xml – engraçado como sua perspectiva muda!)

Agora você poderia 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 adicionado algum valor real a qualquer sistema com o qual trabalhei.

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

Eu diria que o autowiring completo é o ruby-on-rails da primavera: ele 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 ou não ser intencional. Eu vi muita configuração xml ir ao mar com inconsistências – ele é refatorado junto com o código? Não pensei. Essas variações existem por um motivo? Geralmente não.

Dificilmente usamos qualificadores em nossa configuração e encontramos outras maneiras de resolver essas situações. Essa é uma clara “desvantagem” que encontramos: Alteramos um pouco a maneira como codificamos para fazer com que ela interaja mais suavemente com autowiring: um repository de clientes não implementa mais a interface genérica Repository , mas criamos uma interface CustomerRepository que estende o Repository . Às vezes também há um truque ou dois quando se trata de subsorting. Mas normalmente apenas nos aponta na direção de uma tipificação mais forte, o que eu acho quase sempre é uma solução melhor.

Mas sim, você está ligando a um estilo particular de DI que a maioria das primaveras faz. Nós nem mesmo fazemos setters públicos para dependencies (Então você poderia argumentar que somos +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 autowiring completa integra-se perfeitamente ao xml.

A única coisa que precisamos agora é que o @Component , @Autowired e o resto sejam incluídos em um JSR (como o JSR-250 ), então não precisamos nos conectar com o Spring. É assim que as coisas têm acontecido no passado (a coisa java.util.concurrent vem à mente), então eu não ficaria totalmente surpreso se isso acontecesse novamente.

Para mim, aqui é o que eu gosto / desgosto sobre a spring e a fiação automática.

Prós:

  • Auto-fiação se livrar da configuração XML desagradável.
  • Muito mais fácil de usar annotations que permitem injetar diretamente usando campos, methods setter ou construtores. Também permite anotar e ‘qualificar’ seus grãos injetados.

Contras:

  • O uso de fiação automática e annotations faz com que você dependa das bibliotecas do Spring, em que, assim como na configuração XML, você pode optar por executar com ou sem o Spring. Como você disse, você fica preso a uma estrutura de DI.
  • Ao mesmo tempo, gosto de poder “qualificar” os feijões, para mim isso torna o código realmente confuso. Se você precisar injetar o mesmo bean em vários lugares, eu vi o mesmo nome de string repetido todo. Para mim, isso parece ter potencial para erros.

Eu comecei a usar a fiação automática quase exclusivamente no trabalho porque dependemos tanto da integração com o Spring que o problema da dependência é discutível. Eu trabalhei em um projeto Spring MVC que usava auto-fiação extensivamente e foi um pouco difícil de envolver minha cabeça.

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

Estamos mudando do @Autowire de volta para a configuração XML em nosso grande projeto. O problema é um desempenho de boot muito baixo. O scanner de autowiring carrega todas as classs do caminho de class de pesquisa de autowiring, assim, muitas classs são carregadas ansiosamente durante a boot do Spring.

Tem havido muito pouca discussão sobre a mudança de ambientes. A maioria dos projetos em que trabalhei foi um problema real para injetar dependencies, dependendo do ambiente em que estamos trabalhando. Com o xml config é bastante simples com o Spring EL, e não tenho conhecimento de nenhuma solução interessante com annotations. Eu acabei de descobrir um:

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

Deve estar funcionando, mas não é uma boa solução.

Eu mudei para @Autowire. Manter a configuração XML em algo diferente de um pequeno projeto tornou-se uma tarefa por si só e a compreensão foi rapidamente degradada.

O IntelliJ fornece um bom suporte (não perfeito) para annotations do Spring.

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 tornar os objects mutáveis, já que as dependencies não podem mais ser finalizadas, já que os construtores padrão precisam ser fornecidos. Dependências precisam ser injetadas através de setter público, ou não controladas através de @Autowired. [ainda pior injeção de dependência é comprometida com classs que instanciam suas dependencies, eu ainda vejo isso em código recém-escrito!]. Por descontrolado quero dizer, em sistemas grandes, quando múltiplas implementações (ou crianças) do tipo estão disponíveis, fica muito mais envolvido para entender qual das implementações foi @Autowired, uma complexidade que dificulta muito a investigação de bugs. Isso também significa que, supostamente você tem um perfil para o ambiente de teste e outro para produção, seus erros de produção só acontecerão quando dói mais – na produção, em vez de ser capaz de identificar os bugs no ambiente de teste, ou melhor ainda tempo de compilation!

Eu mantenho o meio termo onde eu declaro minha (s) class (s) de configuração, (configuração Spring baseada em java usando @Configuration)

Eu declaro todos os meus beans explicitamente na (s) class (s) de configuração. Eu só uso @Autowired na (s) class (s) de configuração, o objective é limitar a dependência do Spring para a (s) class (s) de configuração

O @Configuration reside em um pacote específico, que é o único lugar onde a verificação de mola é executada. (Isso acelera substancialmente o tempo de início em grandes projetos)

Eu me esforço para tornar todas as minhas classs imutáveis, especialmente o object de dados, JPA, Hibernate e Spring, assim como muitas bibliotecas de serialização parecem minar isso. Afasto-me de qualquer coisa que me force a fornecer setters, ou remover a palavra-chave final da minha declaração de propriedade.

Reduzir as possibilidades de alterar objects depois que eles são criados, reduz substancialmente os erros no sistema grande, bem como reduz o tempo para encontrar um bug quando existe um.

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 mais e mais erros de compilation, o que reduz o desperdício de tempo e melhora a produtividade.

Aqui estão algumas experiências
Prós

  • Facilita a configuração porque podemos usar apenas a anotação @Autowire
  • Não quer usar methods setter, então a class será mais limpa

Contras

  • Firmemente casal para arquivo xml, mesmo que estamos usando DI
  • Difícil de encontrar a implementação (Mas se você está usando bons ides como intellij certeza que você pode se livrar disso)

A partir de minhas experiências pessoais, não usei muito a anotação @AutoWire, mas em casos de teste.

Eu realmente amo escrever com annotations, em vez de XML. De acordo com o manual do Spring e as últimas versões, o XML e o Annotation obtiveram o mesmo resultado.

Esta é minha lista

Pró:

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

Contras:

  • Não é uma implementação Java padrão, mas você pode alternar para usar @Inject, que é uma API Java Standard, portanto, o bean permanece um Pojo
  • Você não pode simplesmente usar em todos os lugares, conexão db e assim por diante, mas é apenas uma opinião, eu prefiro ter um lugar onde leia toda a configuração.

Para minha compreensão, o @Autowired é o melhor para usar enquanto se refere à referência de interface e usa suas funções de substituição, mas eu só acho que o problema com isso é que às vezes é atribuído a null em tempo de execução.