java - with - Entendendo o uso do Spring @Autowired




using autowired in spring boot (2)

Estou lendo a documentação de referência do Spring 3.0.x para entender a anotação do Spring Autowired:

3.9.2 @Autowired e @Inject

Eu não sou capaz de entender os exemplos abaixo. Precisamos fazer algo no XML para que ele funcione?

EXEMPLO 1

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Autowired
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // ...
}

EXEMPLO 2

public class MovieRecommender {

    private MovieCatalog movieCatalog;

    private CustomerPreferenceDao customerPreferenceDao;

    @Autowired
    public void prepare(MovieCatalog movieCatalog,
                    CustomerPreferenceDao customerPreferenceDao) {
        this.movieCatalog = movieCatalog;
        this.customerPreferenceDao = customerPreferenceDao;
    }

    // ...
}

Como as duas classes podem ser autowired implementando a mesma interface e usando a mesma classe?

Exemplo:

class Red implements Color
class Blue implements Color

class myMainClass{
    @Autowired 
    private Color color;

    draw(){
        color.design(); 
    } 
}

Qual método de design será chamado? Como posso ter certeza de que o método de design da classe Red será chamado e não Blue?


Nada no exemplo diz que as "classes implementando a mesma interface". MovieCatalog é um tipo e CustomerPreferenceDao é outro tipo. A primavera pode facilmente diferenciá-los.

No Spring 2.x, a ligação de beans ocorreu principalmente através de IDs de beans ou nomes. Isso ainda é suportado pelo Spring 3.x, mas muitas vezes você terá uma instância de um bean com um certo tipo - a maioria dos serviços são singletons. Criar nomes para esses é tedioso. Então Spring começou a suportar "autowire by type".

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 ser um pouco cuidadoso com interfaces, no entanto:

Esta autowiring falhará:

 @Autowired
 public void prepare( Interface1 bean1, Interface1 bean2 ) { ... }

Como o Java não mantém os nomes dos parâmetros no código de bytes, o Spring não consegue mais distinguir os dois beans. A correção é usar @Qualifier :

 @Autowired
 public void prepare( @Qualifier("bean1") Interface1 bean1,
     @Qualifier("bean2")  Interface1 bean2 ) { ... }

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 básico.

Uma vez que você tenha seu Spring configurado provavelmente, você pode fazer o seguinte no arquivo xml de contexto do servlet Spring para o Exemplo 1 acima para trabalhar ( substitua o nome do pacote de com.movies pelo nome verdadeiro do pacote e se este for um terceiro classe, em seguida, certifique-se de que o arquivo jar apropriado está no caminho de classe):

<beans:bean id="movieFinder" class="com.movies.MovieFinder" />

ou se a classe MovieFinder tem um construtor com um valor primitivo, então você poderia algo assim,

<beans:bean id="movieFinder" class="com.movies.MovieFinder" >
    <beans:constructor-arg value="100" />
</beans:bean>

ou se a classe MovieFinder tem um construtor esperando outra classe, então você poderia fazer algo assim,

<beans:bean id="movieFinder" class="com.movies.MovieFinder" >
    <beans:constructor-arg ref="otherBeanRef" />
</beans:bean>

... onde ' otherBeanRef ' é outro bean que tem uma referência à classe esperada.





spring-3