Guia para Spring @Autowired

Guia para Spring @Autowired

1. Visão geral

A partir do Spring 2.5, o framework introduziu um novo estilo de injeção de dependência dirigido por@Autowired Anotações. Essa anotação permite que o Spring resolva e injete beans colaborativos no seu bean.

Neste tutorial, veremos como habilitar a autowiring, várias anotações de ways to wire in beans,_ making beans optional, resolving bean conflicts using _@Qualifier junto com cenários de exceção em potencial.

Leitura adicional:

Digitalização de componentes Spring

Aprenda sobre o mecanismo por trás da varredura de componentes Spring e como você pode ajustá-lo às suas próprias necessidades

Read more

Introdução à Inversão do Controle e Injeção de Dependência com Mola

Uma rápida introdução aos conceitos de Inversão de Controle e Injeção de Dependência, seguida de uma demonstração simples usando o Spring Framework

Read more

2. Habilitando anotações de@Autowired

Se estiver usando a configuração baseada em Java em seu aplicativo, você pode habilitar a injeção orientada por anotação usandoAnnotationConfigApplicationContext para carregar sua configuração de mola como abaixo:

@Configuration
@ComponentScan("com.example.autowire.sample")
public class AppConfig {}

Como alternativa, no Spring XML, ele pode ser habilitado declarando-o em arquivos Spring XML da seguinte forma:<context:annotation-config/>

3. Usando@Autowired

Depois que a injeção de anotação é ativada, a fiação automática pode ser usada em propriedades, setters e construtores.

3.1. @Autowired em Propriedades

A anotação pode ser usada diretamente nas propriedades, eliminando a necessidade de getters e setters:

@Component("fooFormatter")
public class FooFormatter {

    public String format() {
        return "foo";
    }
}
@Component
public class FooService {

    @Autowired
    private FooFormatter fooFormatter;

}

No exemplo acima, o Spring procura e injetafooFormatter quandoFooService é criado.

3.2. @Autowired em Setters

A anotação@Autowired pode ser usada em métodos de setter. No exemplo abaixo, quando a anotação é usada no método setter, o método setter é chamado com a instância deFooFormatter quandoFooService é criado:

public class FooService {

    private FooFormatter fooFormatter;

    @Autowired
    public void setFooFormatter(FooFormatter fooFormatter) {
            this.fooFormatter = fooFormatter;
    }
}

3.3. @Autowired em construtores

A anotação@Autowired também pode ser usada em construtores. No exemplo a seguir, quando a anotação é usada em um construtor, uma instância deFooFormatter é injetada como um argumento para o construtor quandoFooService é criado:

public class FooService {

    private FooFormatter fooFormatter;

    @Autowired
    public FooService(FooFormatter fooFormatter) {
        this.fooFormatter = fooFormatter;
    }
}

4. Dependências autorizadas e opcionais

Spring espera que as dependências de@Autowired estejam disponíveis quando o bean dependente estiver sendo construído. Se a estrutura não puder resolver um bean para a fiação, lançará a exceção citada abaixo e impedirá que o contêiner Spring seja iniciado com êxito:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [com.autowire.sample.FooDAO] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations:
{@org.springframework.beans.factory.annotation.Autowired(required=true)}

Para evitar que isso aconteça, um bean pode ser opcionalmente especificado como abaixo:

public class FooService {

    @Autowired(required = false)
    private FooDAO dataAccessor;

}

5. Desambiguação do fio automático

Por padrão, o Spring resolve@Autowired entradas por tipo. Se mais de um bean do mesmo tipo estiver disponível no contêiner, a estrutura lançará uma exceção fatal, indicando que mais de um bean está disponível para ligação automática.

5.1. Autowiring por@Qualifier

A anotação@Qualifier pode ser usada para sugerir e restringir o bean necessário:

@Component("fooFormatter")
public class FooFormatter implements Formatter {

    public String format() {
        return "foo";
    }
}
@Component("barFormatter")
public class BarFormatter implements Formatter {

    public String format() {
        return "bar";
    }
}
public class FooService {

    @Autowired
    private Formatter formatter;

}

Uma vez que existem duas implementações concretas deFormatter disponíveis para o contêiner Spring injetar, o Spring lançará uma exceçãoNoUniqueBeanDefinitionException ao construir oFooService: __

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [com.autowire.sample.Formatter] is defined:
expected single matching bean but found 2: barFormatter,fooFormatter

Isso pode ser evitado estreitando a implementação usando uma anotação@Qualifier:

public class FooService {

    @Autowired
    @Qualifier("fooFormatter")
    private Formatter formatter;

}

Ao especificar@Qualifier com o nome da implementação específica, neste caso comofooFormatter, podemos evitar ambigüidade quando o Spring encontra vários beans do mesmo tipo.

Observe que o valor da anotação@Qualifier corresponde ao nome declarado na anotação@Component de nossa implementaçãoFooFormatter.

5.2. Autowiring por Custom Qualifier

O Spring nos permite criar nossa própria anotação@Qualifier. Para criar um qualificador personalizado, defina uma anotação e forneça a anotação@Qualifier dentro da definição conforme abaixo:

@Qualifier
@Target({
  ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface FormatterType {

    String value();

}

Uma vez definido, oFormatterType pode ser usado em várias implementações para especificar o valor personalizado:

@FormatterType("Foo")
@Component
public class FooFormatter implements Formatter {

    public String format() {
        return "foo";
    }
}
@FormatterType("Bar")
@Component
public class BarFormatter implements Formatter {

    public String format() {
        return "bar";
    }
}

Depois que as implementações são anotadas, a anotação qualificada personalizada pode ser usada como abaixo:

@Component
public class FooService {

    @Autowired
    @FormatterType("Foo")
    private Formatter formatter;

}

O valor especificado na anotação@Target restringe onde o qualificador pode ser usado para marcar pontos de injeção.

No trecho de código acima, o qualificador pode ser usado para desambiguar o ponto em que o Spring pode injetar o bean em um campo, um método, um tipo e um parâmetro.

5.3. Autowiring por nome

Como alternativa, o Spring usa o nome do bean como um valor qualificador padrão.

Portanto, ao definir o nome da propriedade do bean, neste caso comofooFormatter,, o Spring combina isso com a implementaçãoFooFormatter e injeta essa implementação específica quandoFooService é construído:

public class FooService {

    @Autowired
    private Formatter fooFormatter;

}

6. Conclusão

Embora tanto@Qualifiere correspondência de fallback de nome de bean possam ser usados ​​para restringir a um bean específico, o autowiring é realmente tudo sobre injeção por tipo e esta é a melhor forma de usar este recurso de contêiner.

O código-fonte deste tutorial pode ser encontrado emthe GitHub project - este é um projeto baseado em Eclipse, portanto, deve ser fácil de importar e executar como está.