Pregunta

Tengo un comportamiento extraño cuando Autowiring

Tengo un código similar como éste, y funciona

@Controller
public class Class1 {
    @Autowired
    private Class2 object2;
    ...
}

@Service
@Transactional
public class Class2{
   ...
}

El problema es que necesito que la Clase 2 implementa una interfaz así que sólo he cambiado la Clase 2 por lo que es ahora como:

@Controller
public class Class1 {
    @Autowired
    private Class2 object2;
    ...
}

@Service
@Transactional
public class Class2 implements IServiceReference<Class3, Long>{
   ...
}

public interface IServiceReference<T, PK extends Serializable> {
    public T reference(PK id);
}

con este código consigo un org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type for Class2. Parece que la anotación @Transitional no es compatible con la interfaz ya que si se quita la anotación @Transitional o la implements IServiceReference<Class3, Long> se inyecta el disapears problema y el frijol (aunque tengo que tener tanto en esta clase). También sucede si pongo la @Transitional anotación en los métodos en lugar de en la Clase.

Yo uso Primavera 3.0.2 si esto ayuda.

No es compatible con la interfaz con el método transaccional? Que sea un error de Primavera?

¿Fue útil?

Solución

El problema es que su Clase 1 necesita una referencia al IServiceReference y no la referencia concreta de la clase 2

@Controller
public class Class1 {
@Autowired
private IServiceReference object2;
    ...
}

La razón de esto es que la primavera es la creación de un proxy dinámico para las clases que se han marcado @Transactional. Así, cuando se crea Class2 su envuelta en un objeto proxy que obviamente no es de tipo Class2 pero es de tipo IServiceReference.

Si desea que el comportamiento de uso de clase 2 con la ayuda del poder que tendrá que activar el CGLIB Lea a continuación:

A partir de resortes Doc:

  

Spring AOP utiliza de forma predeterminada estándar   proxies dinámicos J2SE para servidores proxy AOP.   Esto permite a cualquier interfaz (o conjunto de   interfaces) para ser proxy.

     

Spring AOP también puede usar proxies CGLIB.   Esto es necesario para clases de proxy,   en lugar de las interfaces. CGLIB se usa   por defecto si lo hace un objeto de negocio   no implementar una interfaz. Como están las cosas   buenas prácticas de programa para las interfaces   en lugar de clases, las clases de negocios   normalmente implementar uno o más   interfaces de empresa. Es posible   forzar el uso de CGLIB, en aquellos   casos (con suerte raras) donde se necesita   para asesorar a un método que no es   declarado en una interfaz, o donde   necesidad de pasar un objeto proxy a una   método como un tipo concreto.

     

Es importante comprender el hecho de que   Primavera AOP es basado en proxy. ver el   sección titulada Sección 6.6.1,   “proxies AOP entendimiento” para una   examen detallado de exactamente lo   este detalle de implementación realidad   medios.

Otros consejos

La anotación Transactional instruye primavera para generar objetos proxy alrededor de los granos anotados, para implementar la semántica transaccional. El proxy generado implementará las mismas interfaces como el bean destino. Así que si sus implementos de frijol objetivo IServiceReference, entonces también lo hará el proxy generado.

Si el bean destino no tiene interfaces implementadas, entonces el proxy generado en su lugar ser un subclase del tipo bean destino.

En el ejemplo original, el proxy transaccional será una subclase de Class2, porque Class2 implementado ninguna interfaz. Al cambiar Class2 para implementar IServiceReference, el proxy generada ya no Class2 extendida, y IServiceReference vez implementado. Esto causó su ClassCastException.

El mejor enfoque para esta situación consiste en eliminar la referencia a partir de Class1 Class2, y en lugar de hablar con Class2 puramente a través de sus interfaces. Class2 puede implementar tantas interfaces como quiera, el proxy implementará todos ellos.

puede La fuerza del muelle para generar proxies subclase independientemente de las interfaces, pero es una complejidad adicional, y se lo recomiendo en contra de ella.

Se puede forzar a su representación mediante la adición

@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)

esta documentación .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top