Spring @Primary Annotation

Spring @Primary Annotation

1. Vue d'ensemble

Dans ce rapide didacticiel, nous aborderons l'annotation@Primary de Spring qui a été introduite avec la version 3.0 du framework.

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

Décrivons le problème en détail.

2. Pourquoi@Primary est-il nécessaire?

Dans certains cas,we need to register more than one bean of the same type.

Dans cet exemple, nous avons les beansJohnEmployee() etTonyEmployee() de typeEmployee:

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

Pour accéder aux beans du même type, nous utilisons généralement l'annotation@Qualifier(“beanName”).

Nous l'appliquons au point d'injection avec@Autowired. Dans notre cas, nous sélectionnons les beans lors de la phase de configuration afin que@Qualifier ne puisse pas être appliqué ici. Nous pouvons en savoir plus sur l'annotation@Qualifier en suivant leslink.

Pour résoudre ce problème, Spring propose l'annotation@Primary.

3. Utiliser@Primary avec@Bean

Jetons un œil à la classe de configuration:

@Configuration
public class Config {

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

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

On marqueTonyEmployee() bean avec@Primary. Spring injectera le haricotTonyEmployee() de préférence sur le haricotJohnEmployee().

Maintenant, démarrons le contexte de l'application et récupérons le beanEmployee à partir de celui-ci:

AnnotationConfigApplicationContext context
  = new AnnotationConfigApplicationContext(Config.class);

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

Après avoir exécuté l'application:

Employee{name='Tony'}

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

4. Utiliser@Primary avec@Component

We can use @Primary directly on the beans. Examinons le scénario suivant:

public interface Manager {
    String getManagerName();
}

Nous avons une interfaceManager et deux beans de sous-classe,DepartmentManager:

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

Et le beanGeneralManager:

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

Ils remplacent tous les deux lesgetManagerName() de l'interfaceManager. Notez également que nous marquons leGeneralManager bean avec@Primary.

Cette fois,@Primary only makes sense when we enable the component scan:

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

Créons un service pour utiliser l'injection de dépendances tout en trouvant le bon bean:

@Service
public class ManagerService {

    @Autowired
    private Manager manager;

    public Manager getManager() {
        return manager;
    }
}

Ici, les deux beansDepartmentManager andGeneralManager sont éligibles pour l'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());

La sortie est «General manager”.

5. Conclusion

Dans cet article, nous avons découvert l'annotation@Primary de Spring. Avec les exemples de code, nous avons démontré le besoin et les cas d'utilisation des@Primary.

Comme d'habitude, le code complet de cet article est disponibleover on GitHub project.