1. Información general
En este tutorial rápido, discutiremos la anotación @Primary de Spring que se introdujo con la versión 3.0 del marco.
En pocas palabras, usamos @Primary para dar mayor preferencia a un bean cuando hay varios beans del mismo tipo.
Describamos el problema en detalle.
2. ¿Por qué se necesita @Primary ?
En algunos casos, necesitamos registrar más de un bean del mismo tipo .
En este ejemplo tenemos los beans JohnEmployee () y TonyEmployee () del tipo Empleado :
@Configuration public class Config { @Bean public Employee JohnEmployee() { return new Employee("John"); } @Bean public Employee TonyEmployee() { return new Employee("Tony"); } }
Spring lanza NoUniqueBeanDefinitionException si intentamos ejecutar la aplicación .
Para acceder a beans con el mismo tipo usualmente usamos la anotación @Qualifier ("beanName") .
Lo aplicamos en el punto de inyección junto con @Autowired . En nuestro caso, seleccionamos los beans en la fase de configuración para que @Qualifier no se pueda aplicar aquí. Podemos obtener más información sobre la anotación @Qualifier siguiendo el enlace.
Para resolver este problema, Spring ofrece la anotación @Primary .
3. Utilice @Primary con @Bean
Echemos un vistazo a la clase de configuración:
@Configuration public class Config { @Bean public Employee JohnEmployee() { return new Employee("John"); } @Bean @Primary public Employee TonyEmployee() { return new Employee("Tony"); } }
Marcamos TonyEmployee () de frijoles con @Primary . Spring inyectará el bean TonyEmployee () preferentemente sobre JohnEmployee () .
Ahora, comencemos el contexto de la aplicación y obtengamos el bean Empleado de él:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class); Employee employee = context.getBean(Employee.class); System.out.println(employee);
Después de ejecutar la aplicación:
Employee{name='Tony'}
A partir de la salida, podemos ver que la instancia de TonyEmployee () tiene una preferencia durante el cableado automático .
4. Utilice @Primary con @Component
Podemos usar @Primary directamente en los beans . Echemos un vistazo al siguiente escenario:
public interface Manager { String getManagerName(); }
Tenemos una interfaz de administrador y dos beans de subclase, DepartmentManager :
@Component public class DepartmentManager implements Manager { @Override public String getManagerName() { return "Department manager"; } }
Y el bean GeneralManager :
@Component @Primary public class GeneralManager implements Manager { @Override public String getManagerName() { return "General manager"; } }
Ambos anulan el getManagerName () de la interfaz del administrador . Además, tenga en cuenta que marcamos el bean GeneralManager con @Primary .
Esta vez, @Primary solo tiene sentido cuando habilitamos el escaneo de componentes :
@Configuration @ComponentScan(basePackages="org.baeldung.primary") public class Config { }
Creemos un servicio para usar la inyección de dependencias mientras encontramos el bean correcto:
@Service public class ManagerService { @Autowired private Manager manager; public Manager getManager() { return manager; } }
Aquí, tanto los beans DepartmentManager como el GeneralManager son elegibles para el cableado automático.
Como marcamos el bean GeneralManager con @Primary , se seleccionará para la inyección de dependencia :
ManagerService service = context.getBean(ManagerService.class); Manager manager = service.getManager(); System.out.println(manager.getManagerName());
La salida es " Gerente general".
5. Conclusión
En este artículo, aprendimos sobre la anotación @Primary de Spring . Con los ejemplos de código, demostramos la necesidad y los casos de uso de @Primary.
Como de costumbre, el código completo de este artículo está disponible en el proyecto GitHub.