TL; DR
A anotação @Autowired poupa você da necessidade de fazer a fiação sozinha no arquivo XML (ou de qualquer outra maneira) e apenas descobre o que precisa ser injetado onde e o faz.
Explicação completa
A @Autowired
anotação permite que você pule as configurações em outro lugar do que injetar e apenas faz isso por você. Supondo que seu pacote seja necessário, com.mycompany.movies
você deve colocar essa tag no seu XML (arquivo de contexto do aplicativo):
<context:component-scan base-package="com.mycompany.movies" />
Essa tag fará uma verificação automática. Supondo que cada classe que precisa se tornar um bean seja anotada com uma anotação correta, como @Component
(para bean simples) ou @Controller
(para um controle de servlet) ou @Repository
(para DAO
classes) e essas classes estiverem em algum lugar no pacote com.mycompany.movies
, o Spring encontrará tudo isso e criará um feijão para cada um. Isso é feito em duas varreduras das classes - na primeira vez, apenas procura por classes que precisam se tornar um bean e mapeia as injeções necessárias e, na segunda varredura, ele injeta os beans. Obviamente, você pode definir seus beans no arquivo XML mais tradicional ou com um @Configuration classe (ou qualquer combinação das três).
A @Autowired
anotação informa ao Spring onde uma injeção precisa ocorrer. Se você o colocar em um método, setMovieFinder
ele entenderá (pelo prefixo set
+ a @Autowired
anotação) que um bean precisa ser injetado. Na segunda varredura, o Spring procura um bean do tipo MovieFinder
e, se o encontrar, o injeta nesse método. Se encontrar dois desses feijões, você receberá um Exception
. Para evitar isso Exception
, você pode usar a @Qualifier
anotação e dizer qual dos dois beans injetar da seguinte maneira:
@Qualifier("redBean")
class Red implements Color {
// Class code here
}
@Qualifier("blueBean")
class Blue implements Color {
// Class code here
}
Ou se você preferir declarar os beans em seu XML, seria algo parecido com isto:
<bean id="redBean" class="com.mycompany.movies.Red"/>
<bean id="blueBean" class="com.mycompany.movies.Blue"/>
Na @Autowired
declaração, você também precisa adicionar o @Qualifier
para informar qual dos dois beans coloridos injetar:
@Autowired
@Qualifier("redBean")
public void setColor(Color color) {
this.color = color;
}
Se você não quiser usar duas anotações (the @Autowired
e @Qualifier
), poderá usá @Resource
-las para combinar essas duas:
@Resource(name="redBean")
public void setColor(Color color) {
this.color = color;
}
O @Resource
(você pode ler alguns dados extras sobre isso no primeiro comentário sobre esta resposta) poupa o uso de duas anotações e, em vez disso, usa apenas uma.
Vou apenas adicionar mais dois comentários:
- A boa prática seria usar em
@Inject
vez de, @Autowired
porque não é específica da Primavera e faz parte do JSR-330
padrão .
- Outra boa prática seria colocar o
@Inject
/ @Autowired
em um construtor em vez de em um método. Se você o colocar em um construtor, poderá validar que os beans injetados não são nulos e falham rapidamente ao tentar iniciar o aplicativo e evitar um NullPointerException
quando você realmente precisa usá-lo.
Atualização : Para completar a figura, criei uma nova pergunta sobre a @Configuration
turma.
MovieFinder
é uma interface e temos um bean paraMovieFinderImpl
(bean id = movieFinder), o Spring injeta automaticamente por tipo ou por nome?@Qualifier
. Se você fizer - por nome, se não - por tipo. Por tipo funcionaria apenas se você tiver apenas um bean do tipoMovieFinder
em seu contexto. Mais de 1 levaria a uma exceção.@Autowired
anotação funciona noprepare
método do Exemplo 2 . Está inicializando oMovieRecommender
, mas, tecnicamente, NÃO é um levantador.@Autowired
também funciona para construtores. Ele encontra as dependências necessárias e as injeta no construtor.Nada no exemplo diz que as "classes implementando a mesma interface".
MovieCatalog
é um tipo eCustomerPreferenceDao
é outro tipo. A primavera pode diferenciá-los facilmente.Na primavera 2.x, a fiação dos beans acontecia principalmente por meio de IDs ou nomes de beans. Isso ainda é suportado pelo Spring 3.x, mas muitas vezes você terá uma instância de um bean com um determinado tipo - a maioria dos serviços são singletons. Criar nomes para eles é entediante. Então, o Spring começou a suportar "autowire por tipo".
O que os exemplos mostram são várias maneiras que você pode usar para injetar beans em campos, métodos e construtores.
O XML já contém todas as informações que o Spring precisa, pois é necessário especificar o nome completo da classe em cada bean. Você precisa ter um pouco de cuidado com as interfaces:
Essa fiação automática falhará:
Como o Java não mantém os nomes dos parâmetros no código de bytes, o Spring não pode mais distinguir entre os dois beans. A correção é usar
@Qualifier
:fonte
prepare
, quais parâmetros serão usados para chamar essa função?@Autowired
campos são injetados. O Spring verá que os parâmetros são necessários e usará as mesmas regras usadas para injeção de campo para encontrar os parâmetros.Sim, você pode configurar o arquivo xml de contexto do servlet Spring para definir seus beans (ou seja, classes), para que ele possa fazer a injeção automática para você. No entanto, observe que você precisa fazer outras configurações para ter o Spring instalado e funcionando e a melhor maneira de fazer isso é seguir um tutorial completo.
Depois que o Spring estiver configurado, provavelmente, você poderá fazer o seguinte no arquivo xml de contexto do servlet do Spring para o Exemplo 1 acima ( substitua o nome do pacote de com.movies pelo nome verdadeiro do pacote e se este é um terceiro classe, verifique se o arquivo jar apropriado está no caminho de classe):
ou se a classe MovieFinder tiver um construtor com um valor primitivo, você poderá algo assim,
ou se a classe MovieFinder tiver um construtor esperando outra classe, você poderá fazer algo assim,
... onde ' otherBeanRef ' é outro bean que tem uma referência à classe esperada.
fonte
@Autowired