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