2012-07-18 15 views
6

Necesito buscar frijoles a través de su tipo de clase. Cuando los beans han sido envueltos por un Proxy (algunos métodos son @Transactional) - el ApplicatoinContext no los encuentra. Me parece que si los busco a través de una interfaz, funciona, pero en este caso estoy trabajando con un tipo de clase concreto. Sé que el bean es del tipo que estoy buscando, pero el método getBean() falla.Spring ApplicationContext.getBean (Clase c) no funciona para las clases proxy

Puedo depurar (y corregir) el problema en el código AbstractBeanFactory de Spring. El problema es que comprueba el tipo de beanInstance contra el tipo que estoy solicitando, pero el beanInstance.getClass() es un proxy. AbstractBeanFactory debería compensar esto y comparar el tipo con la clase objetivo del proxy.

Tengo una solución para esto pero particularmente no quiero usar una versión parcheada de Spring y sospecho que debe haber algo que pueda configurar para que funcione, ¿o es realmente un error?

Respuesta

11

Hay dos formas principales en que Spring implementa AOP (por ejemplo, compatibilidad con @Transactional): ya sea mediante el uso de interfaces proxy o CGLIB.

Con interfaces (por defecto) si su clase implementa alguna interfaz, Spring creará un proxy que implementará todas las interfaces. A partir de ahora solo puedes trabajar con tu bean a través de esas interfaces. Tu clase está profundamente enterrada dentro de ellos.

Si habilita proxy a través de clases de objetivos en lugar :

<aop:config proxy-target-class="true"> 

primavera creará una subclase (muy movido todavía la aplicación de todas las interfaces) en su lugar. Esto solucionará tu problema. Sin embargo, recuerde que el objeto devuelto no es realmente su clase sino una subclase generada dinámicamente que envuelve y delega en su objeto original. Esto no debería ser un problema en la mayoría de los casos.

Y no, por supuesto esto no es un error, pero el comportamiento bien conocido y no, no hay necesidad de parche de primavera.

Ver también

+0

Gracias por la explicación: descubrí que podía recuperar mi bean a través de una interfaz. Pensé en usar eso, pero el problema es que absolutamente necesito referirme a la clase concreta en mi situación (la clase concreta también implementa otra interfaz en la que estoy confiando). Llegué a la conclusión de que utilizaría la opción GCLIB hoy para evitarlo. ¿Por qué alguien no querría usar eso? En cuanto a usar clases proxy, ¡esto me huele a un error, no a una 'característica'! –

+0

@AlexWorden: si su clase implementa varias interfaces, puede obtener bean por cualquiera de ellas. Una de las desventajas de CGLIB es que ... debe usar CGLIB (biblioteca externa). Bueno, no es un error ni una característica: Spring tiene que implementar AOP de alguna manera y estas son las dos características más comunes. Además, CGLIB tiene otros efectos secundarios, como la creación de dos instancias de su clase en lugar de una. Dos mucho por un comentario –

1
<context:component-scan base-package="<Your base package name goes here>" /> 
<aop:aspectj-autoproxy /> 
<aop:config proxy-target-class="true"/> 

escribir estas tres líneas en este applicationContext.xml trabajó para mi.

Cuestiones relacionadas