2010-03-05 14 views
40

que tienen esta configuración de primavera:Spring Autowiring clase vs. interfaz?

<bean id="boo" class="com.x.TheClass"/> 

La clase TheClass implementos TheInterface. Entonces tengo este código (hipotética) de Java:

@Autowired 
TheInterface x; 

@Autowired 
TheClass y; 

El autowiring de TheInterface obras pero el autowiring de TheClass falla. Spring me da un NoSuchBeanDefinitionException para la clase.

¿Por qué se puede conectar la interfaz y no la clase?

+6

¿Hay algo especial en esta clase, como que sea 'final' o que tenga otra instrumentación, como @Transactional, en ella? Es posible que le falte una lib de instrumentación, como CGLIB, o intente crear un proxy de subclase en una clase final. – ptomli

Respuesta

54

Normalmente, ambos funcionarán, puede autoconectar interfaces o clases.

Probablemente haya un generador de autoproxy en algún lugar de su contexto, que está envolviendo su bean boo en un objeto proxy generado. Este objeto proxy implementará TheInterface, pero no será un TheClass. Al usar autoproxies, necesita programar en la interfaz, no en la implementación.

El candidato probable son los proxies transaccionales: ¿está utilizando transacciones Spring, utilizando AspectJ o @Transactional?

+0

Sí, tiene '@ Transactional', parece que este escenario no es válido. –

+5

@Marcus: Ese es el problema entonces. Si usa '@ Transactional' y' ', no puede convertir el bean en' MyClass', debe usar la interfaz. – skaffman

+27

Sé que esto es un poco antiguo, pero para agregar un poco aquí ... No tiene que usar la interfaz, pero para poder autoaumentar la clase directamente, necesita modificar el ' 'y agregue' proxy-target-class = "true" '(por defecto es falso). Esto le permite auto-conectarse directamente a la clase. Tenga en cuenta que puede haber efectos secundarios extraños, p. He usado algunos reflejos para encontrar el tipo parametrizado para una clase base genérica. La herencia ha cambiado debido a la clase proxy, así que tuve que tomar eso en cuenta. Todavía puede conectar por interfaz con 'proxy-target-class =" true "'. –