vista que patrón mvc modelo ejemplo controlador java spring spring-mvc autowired

java - patrón - Autocableo de dos beans que implementan la misma interfaz: ¿cómo configurar el bean predeterminado para que se autoenlace?



mvc java swing mysql (3)

¿Qué hay de @Primary ?

Indica que se debe dar preferencia a un bean cuando varios candidatos están calificados para autoautar una dependencia de un solo valor. Si existe exactamente un bean ''primario'' entre los candidatos, será el valor de autoenlace. Esta anotación es semánticamente equivalente al atributo primary del elemento <bean> en Spring XML.

@Primary public class HibernateDeviceDao implements DeviceDao

O si desea que su versión de Jdbc se use de manera predeterminada:

<bean id="jdbcDeviceDao" primary="true" class="com.initech.service.dao.jdbc.JdbcDeviceDao">

@Primary también es ideal para las pruebas de integración cuando puede reemplazar fácilmente al bean de producción con la versión @Primary .

Fondo:

Tengo una aplicación Spring 2.5 / Java / Tomcat. Hay el siguiente bean, que se utiliza en toda la aplicación en muchos lugares

public class HibernateDeviceDao implements DeviceDao

y el siguiente frijol que es nuevo:

public class JdbcDeviceDao implements DeviceDao

El primer bean está configurado así (todos los beans en el paquete están incluidos)

<context:component-scan base-package="com.initech.service.dao.hibernate" />

El segundo bean (nuevo) se configura por separado

<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao"> <property name="dataSource" ref="jdbcDataSource"> </bean>

Esto resulta (por supuesto) en una excepción al iniciar el servidor:

la excepción anidada es org.springframework.beans.factory.NoSuchBeanDefinitionException: no se define ningún bean único del tipo [com.sevenp.mobile.samplemgmt.service.dao.DeviceDao]: bean de coincidencia única esperada pero se encontró 2: [deviceDao, jdbcDeviceDao]

de una clase tratando de autoautar el frijol como este

@Autowired private DeviceDao hibernateDevicDao;

porque hay dos beans implementando la misma interfaz.

La pregunta:

¿Es posible configurar los beans para que

1. No tengo que hacer cambios en las clases existentes, que ya tienen el HibernateDeviceDao Dao autoguardado

2. aún pudiendo usar el segundo bean (nuevo) como este:

@Autowired @Qualifier("jdbcDeviceDao")

Es decir, necesitaría una forma de configurar el bean HibernateDeviceDao como bean predeterminado para que se autoconecte, permitiendo simultáneamente el uso de un JdbcDeviceDao al especificarlo explícitamente con la anotación @Qualifier .

Lo que ya he intentado:

Intenté configurar la propiedad

autowire-candidate="false"

en la configuración de beans para JdbcDeviceDao:

<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao" autowire-candidate="false"> <property name="dataSource" ref="jdbcDataSource"/> </bean>

porque la documentación de Spring dice que

Indica si este bean se debe considerar al buscar candidatos coincidentes para satisfacer los requisitos de autowiring de otro bean. Tenga en cuenta que esto no afecta a las referencias explícitas por nombre, que se resolverán incluso si el bean especificado no está marcado como un candidato de autowire. *

lo cual interpreté que significaba que aún podía autoconectar JdbcDeviceDao usando la anotación @Qualifier y tener el HibernateDeviceDao como bean predeterminado. Aparentemente, mi interpretación no era correcta, ya que esto genera el siguiente mensaje de error al iniciar el servidor:

Dependencia insatisfecha de tipo [class com.sevenp.mobile.samplemgmt.service.dao.jdbc.JdbcDeviceDao]: se esperaba al menos 1 bean coincidente

viniendo de la clase donde intenté autover el bean con un calificador:

@Autowired @Qualifier("jdbcDeviceDao")

Solución:

skaffman''s suggestion skaffman''s para probar la anotación @Resource funcionó. Entonces, la configuración tiene el autowire-candidate establecido en falso para jdbcDeviceDao y cuando uso el jdbcDeviceDao, me refiero a él usando la anotación @Resource (en lugar de @Qualifier):

@Resource(name = "jdbcDeviceDao") private JdbcDeviceListItemDao jdbcDeviceDao;


Para Spring 2.5, no hay @Primary . La única forma es usar @Qualifier .


Sugiero marcar la clase DAO de Hibernate con @Primary , es decir (suponiendo que utilizas @Repository en HibernateDeviceDao ):

@Primary @Repository public class HibernateDeviceDao implements DeviceDao

De esta forma se seleccionará como el candidato predeterminado para el autowire, sin necesidad de autowire-candidate en el otro bean.

Además, en lugar de utilizar @Autowired @Qualifier , me parece más elegante usar @Resource para seleccionar beans específicos, es decir,

@Resource(name="jdbcDeviceDao") DeviceDao deviceDao;