java - sirve - qualifier example
Spring Autowiring solo funciona con Interface (6)
Desde lo poco que he visto hasta ahora, no parece haber ninguna restricción con respecto al tipo de clase que se podría marcar como @Autowired.
No relacionado con el problema, pero this artículo hace referencia a la situación en sí.
Soy bastante nuevo en Spring Framework y encontré el siguiente problema.
Tengo una interfaz ClassA
, que es implementada por ClassA1
y ClassA2
.
Tengo la siguiente definición de bean agregada a applicationContext.xml
<bean id="class1" class="com.abc.ClassA1" />
<bean id="class2" class="com.abc.ClassA2" />
Me gustaría Autowire tanto las clases de implementación como a continuación.
@Autowired
private ClassA1 classA1;
@Autowired
private ClassA2 classA2;
El código anterior está arrojando error como
No se pudo escribir automáticamente en el campo: com.abc.ClassA1 com.abc.SomeClass.classA1; la excepción anidada es org.springframework.beans.factory.NoSuchBeanDefinitionException: No hay ningún bean coincidente de tipo [com.abc.ClassA1]
Pero, si cambio la conexión automática a la interfaz de la siguiente manera:
@Autowired
ClassA classA1;
Entonces ClassA1 se conecta automáticamente a la variable. No tengo ni idea de cómo puedo crear automáticamente una variable para ClassA2.
Intenté varias formas de solucionar este problema, pero funcionó de la siguiente manera.
@Autowired
private ClassA classA1;
@Autowired
private ClassA classA2;
En el contexto de la aplicación, definí el bean de la siguiente manera:
<bean id="classA1" class="com.abc.ClassA1" autowire="byName" />
<bean id="classA2" class="com.abc.ClassA2" autowire="byName" />
Podrías usar la anotación @Qualifier
:
@Autowired
@Qualifier("class1")
ClassA classA1;
@Autowired
@Qualifier("class2")
ClassA classA2;
o la anotación @Resource
:
@Resource(name="class1")
ClassA classA1;
@Resource(name="class2")
ClassA classA2;
Por alguna razón tus clases son apoderadas por Spring. Hay muchas razones por las que esto puede suceder. Por ejemplo, si usa JPA, o AOP, la clase original es proxy.
Si una clase implementa una interfaz, proxy significa Proxy dinámico. Básicamente, se crea una nueva clase en tiempo de ejecución que implementa las interfaces pero no hereda de la clase original. Por lo tanto, la conexión automática a la clase original no funciona.
Si sus objetos son proxy por proxies JDK, entonces deben ser referidos por su interfaz. Puede hacer proxies por clase concreta utilizando CGLIB (en la ruta proxy-target-class="true"
) y proxy-target-class="true"
en su configuración aop (en applicationContext.xml
)
Tengo un problema similar con Autowiring abstract service. Puede utilizar sin ningún código de problema como este:
@Autowired
@Qualifier("classA1")
private ClassA1 classA1;
@Autowired
@Qualifier("classA2")
private ClassA2 classA2;
Esto funcionará solo si declara su bean como este
<bean id="class1" class="com.abc.ClassA1" />
O así
@Component("classA1")
public class ClassA1 {
...
}