Anotação Primária @ Spring

Anotação Primária @ Spring

1. Visão geral

Neste tutorial rápido, discutiremos a anotação de@Primary do Spring que foi introduzida com a versão 3.0 do framework.

Simplificando,we use @Primary to give higher preference to a bean when there are multiple beans of the same type.

Vamos descrever o problema em detalhes.

2. Por que@Primary é necessário?

Em alguns casos,we need to register more than one bean of the same type.

Neste exemplo, temosJohnEmployee()eTonyEmployee() beans do tipoEmployee:

@Configuration
public class Config {

    @Bean
    public Employee JohnEmployee() {
        return new Employee("John");
    }

    @Bean
    public Employee TonyEmployee() {
        return new Employee("Tony");
    }
}

Spring throws NoUniqueBeanDefinitionException if we try to run the application.

Para acessar beans com o mesmo tipo, geralmente usamos a anotação@Qualifier(“beanName”).

Nós o aplicamos no ponto de injeção junto com@Autowired. Em nosso caso, selecionamos os beans na fase de configuração, portanto@Qualifier não pode ser aplicado aqui. Podemos aprender mais sobre a anotação@Qualifier seguindo olink.

Para resolver esse problema, o Spring oferece a anotação@Primary.

3. Use@Primary com@Bean

Vamos dar uma olhada na classe de configuração:

@Configuration
public class Config {

    @Bean
    public Employee JohnEmployee() {
        return new Employee("John");
    }

    @Bean
    @Primary
    public Employee TonyEmployee() {
        return new Employee("Tony");
    }
}

Marcamos o beanTonyEmployee() com@Primary. O Spring injetaráTonyEmployee() bean preferencialmente sobre oJohnEmployee().

Agora, vamos iniciar o contexto do aplicativo e obter o beanEmployee dele:

AnnotationConfigApplicationContext context
  = new AnnotationConfigApplicationContext(Config.class);

Employee employee = context.getBean(Employee.class);
System.out.println(employee);

Depois de executar o aplicativo:

Employee{name='Tony'}

From the output, we can see that the TonyEmployee() instance has a preference while autowiring.

4. Use@Primary com@Component

We can use @Primary directly on the beans. Vamos dar uma olhada no seguinte cenário:

public interface Manager {
    String getManagerName();
}

Temos uma interfaceManager e dois beans de subclasse,DepartmentManager:

@Component
public class DepartmentManager implements Manager {
    @Override
    public String getManagerName() {
        return "Department manager";
    }
}

E o feijãoGeneralManager:

@Component
@Primary
public class GeneralManager implements Manager {
    @Override
    public String getManagerName() {
        return "General manager";
    }
}

Ambos substituem ogetManagerName() da interfaceManager. Além disso, observe que marcamos oGeneralManager bean com@Primary.

Desta vez,@Primary only makes sense when we enable the component scan:

@Configuration
@ComponentScan(basePackages="org.example.primary")
public class Config {
}

Vamos criar um serviço para usar injeção de dependência enquanto encontramos o bean certo:

@Service
public class ManagerService {

    @Autowired
    private Manager manager;

    public Manager getManager() {
        return manager;
    }
}

Aqui, ambos os beansDepartmentManager andGeneralManager são elegíveis para autowiring.

As we marked GeneralManager bean with @Primary, it will be selected for dependency injection:

ManagerService service = context.getBean(ManagerService.class);
Manager manager = service.getManager();
System.out.println(manager.getManagerName());

A saída é “General manager”.

5. Conclusão

Neste artigo, aprendemos sobre a anotação@Primary de Spring. Com os exemplos de código, demonstramos a necessidade e os casos de uso de@Primary.

Como de costume, o código completo deste artigo está disponívelover on GitHub project.