2009-01-08 15 views
19

Quiero declarar dos beans e instanciarlos usando la inyección de dependencia de Spring?Cómo cablear frijoles interdependientes en primavera?

<bean id="sessionFactory" class="SessionFactoryImpl"> 
<property name="entityInterceptor" ref="entityInterceptor"/> 
</bean> 

<bean id="entityInterceptor" class="EntityInterceptorImpl"> 
<property name="sessionFactory" ref="sessionFactory"/> 
</bean> 

pero la primavera se produce una excepción diciendo "FactoryBean que se encuentra actualmente en la creación regresó nula de getObject"

¿Por qué es el cableado de frijol interdependiente no trabaja aquí? ¿Debo especificar la propiedad defferred vinculante en cualquier lugar?

Respuesta

13

Desafortunadamente, la manera en que la inicialización del contenedor funciona en Spring, un bean solo se puede inyectar en otro bean una vez que se haya inicializado por completo. En su caso, tiene una dependencia circular que impide que cualquiera de los beans se inicialice porque dependen el uno del otro. Para evitar esto, puede implementar BeanFactoryAware en uno de los beans y obtener la referencia al otro bean usando beanFactory.getBean ("beanName").

+0

No tengo este problema cuando probé con clases simples como BeanA y BeanB. – Sathish

+0

I segundo Sathish. Puedes hacer esto con 'BeanA' y' BeanB', por lo que es algo más especial sobre este ejemplo. –

+1

Mejor aún, no codifique '' beanName "', sino que use la etiqueta '' de Spring para que la fábrica inyecte el nombre de bean en una propiedad 'String'. – Darien

3

neesh tiene razón, Spring no hace esto de la caja.

Los frijoles interdependientes apuntan a un problema de diseño. La forma "limpia" de hacerlo es rediseñar sus servicios de tal manera que no existan dependencias tan extrañas, por supuesto, siempre que tenga control sobre las implementaciones.

+0

+1 para rediseñar - no debería necesitar tal interdependencia. –

+1

No creo que su diseño esté en duda aquí (no sabemos nada del problema y la solución); La pregunta aquí es cómo se puede tratar con las dependencias circulares entre los objetos administrados por el contenedor de Spring. – neesh

+0

Y la respuesta, en mi humilde opinión, es no hacerlo, a menos que no tenga otra opción porque la implementación no es suya, en cuyo caso las soluciones proporcionadas aquí serán suficientes. Los dos servicios son solo un servicio o hay un tercer servicio de alto nivel esperando a ser descubierto. – Henning

0

se puede ampliar el ApplicactionContext que están utilizando y anula el método createBeanFactory()

protected DefaultListableBeanFactory createBeanFactory(){ 
    DefaultListableBeanFactory beanFactory = super.createBeanFactory(); 
    // By default this is false; 
    beanFactory.setAllowRawInjectionDespiteWrapping(true); 
    return beanFactory; 
} 

Esto funciona, pero tenga cuidado porque esto permite referencias circulares.

Cuestiones relacionadas