2012-04-04 17 views
27

estoy usando resorte 3, y tengo dos granos de vista alcance:Bean solicitado se encuentra actualmente en la creación: ¿Existe una referencia circular no resuelta?

1- Bean1:

@Component("bean1") 
@Scope("view") 
public class Bean1 { 

@Autowired 
private Bean2 bean2; 

} 

2- Bean2:

@Component("bean2") 
@Scope("view") 
public class Bean2 { 

@Autowired 
private Bean1 bean1; 

} 

la vista es un ámbito personalizado:

<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"> 
     <property name="scopes"> 
      <map> 
       <entry key="view"> 
        <bean class="${project.groupId}.utils.ViewScope" /> 
       </entry> 
      </map> 
     </property> 
    </bean> 

y aquí está el código para el alcance vista personalizada:

public class ViewScope implements Scope { 

    @SuppressWarnings("rawtypes") 
    public Object get(String name, ObjectFactory objectFactory) { 
     Map<String, Object> viewMap = FacesContext.getCurrentInstance() 
       .getViewRoot().getViewMap(); 

     if (viewMap.containsKey(name)) { 
      return viewMap.get(name); 
     } else { 
      Object object = objectFactory.getObject(); 
      viewMap.put(name, object); 

      return object; 
     } 
    } 

    public Object remove(String name) { 
     return FacesContext.getCurrentInstance().getViewRoot().getViewMap() 
       .remove(name); 
    } 

    public String getConversationId() { 
     return null; 
    } 

    public void registerDestructionCallback(String name, Runnable callback) { 
     // Not supported 
    } 

    public Object resolveContextualObject(String key) { 
     return null; 
    } 
} 

al abrir la página que utiliza ambos granos, consigo la excepción:

org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'agencyBean': Requested bean is currently in creation: Is there an unresolvable circular reference? 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:252) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:844) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:786) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:474) 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:329) 
    at com.myapp.utils.ViewScope.get(ViewScope.java:20) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:325) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:844) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:786) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:474) 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:329) 
    at com.xeno.xecamp.webManagement.utils.ViewScope.get(ViewScope.java:20) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:325) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190) 
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1075) 
    at org.springframework.beans.factory.access.el.SpringBeanELResolver.getValue(SpringBeanELResolver.java:56) 
    at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176) 
    at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203) 
    at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:71) 
    at org.apache.el.parser.AstValue.getTarget(AstValue.java:94) 
    at org.apache.el.parser.AstValue.invoke(AstValue.java:244) 
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278) 
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) 
    at com.sun.faces.facelets.tag.jsf.core.DeclarativeSystemEventListener.processEvent(EventHandler.java:128) 
    at javax.faces.component.UIComponent$ComponentSystemEventListenerAdapter.processEvent(UIComponent.java:2508) 
    at javax.faces.event.SystemEvent.processListener(SystemEvent.java:106) 
    at com.sun.faces.application.ApplicationImpl.processListeners(ApplicationImpl.java:2139) 
    at com.sun.faces.application.ApplicationImpl.invokeComponentListenersFor(ApplicationImpl.java:2087) 
    at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:286) 
    at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:244) 
    at org.springframework.faces.webflow.Jsf2FlowApplication.publishEvent(Jsf2FlowApplication.java:94) 
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:108) 
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) 
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139) 
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:118) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:368) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:99) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:60) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:119) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:57) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:169) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:70) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:684) 
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:471) 
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:402) 
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329) 
    at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:110) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:368) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:119) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:380) 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:169) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:304) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    at java.lang.Thread.run(Thread.java:619) 

favor aconsejan cómo solucionar este problema es la excepción.

EDITAR: i trató de usar la inyección colocador como se indica en la respuesta aquí

Understanding Spring context initialization order

pero doesn a trabajar también.

1- Bean1:

@Component("bean1") 
@Scope("view") 
public class Bean1 { 


private Bean2 bean2; 

@Autowired 
public void setBean2 (Bean2 bean2) { 
    this.bean2= bean2; 
} 

} 

2- Bean2:

@Component("bean2") 
@Scope("view") 
public class Bean2 { 


private Bean1 bean1; 

@Autowired 
public void setBean1 (Bean1 bean1) { 
    this.bean1= bean1; 
} 

} 

pero me da la excepción:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.myapp.beans.Bean1] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {} 
+2

Para resolver el problema con la dependencia circular, debe eliminar una dependencia de autoenlace y configurarla más tarde (con @PostConstruct o algo similar). Vea el ejemplo 'sinuhepop' a continuación. –

+0

Este artículo ayuda a quién está buscando una respuesta. http://www.baeldung.com/circular-dependencies-in-spring – bpedroso

Respuesta

45

Spring utiliza una lógica especial para resolver este tipo de dependencias circulares con beans singleton. Pero esto no se aplicará a otros ámbitos. No hay una manera elegante de romper esta dependencia circular, sino una opción torpe podría ser ésta:

@Component("bean1") 
@Scope("view") 
public class Bean1 { 

    @Autowired 
    private Bean2 bean2; 

    @PostConstruct 
    public void init() { 
     bean2.setBean1(this); 
    } 
} 

@Component("bean2") 
@Scope("view") 
public class Bean2 { 

    private Bean1 bean1; 

    public void setBean1(Bean1 bean1) { 
     this.bean1 = bean1; 
    } 
} 

De todos modos, dependencias circulares son generalmente un síntoma de un mal diseño. Pensarías nuevamente si hay alguna forma mejor de definir tus dependencias de clase.

+8

De acuerdo, DI o no, las dependencias circulares son difíciles de mantener y deben evitarse. –

+4

Hay ciertos casos donde las dependencias circulares tienen perfecto sentido. Al igual que el patrón de delegados en Cocoa. Un controlador de vista actúa como el delegado de una vista. –

1

En general, la forma de ocuparse de las dependencias circulares es usar s inyección de etter.

Probé el código de inyección setter que publicó, y funcionó para mí. Me imagino que la razón por la que recibes la excepción es porque Bean1 y Bean2 están en el paquete com.myapp.beans, y no tienes habilitado el escaneo de componentes para ese paquete.

Se necesitaría añadir lo siguiente a la configuración de la primavera:

<context:component-scan base-package="com.bullethq.accounts.web"/> 

o mover los granos a un paquete que se está escaneando automáticamente por primavera.

+1

Msaleh está utilizando la inyección de setter en ambos casos (a diferencia de la inyección de argumento de constructor). Su prueba funcionó probablemente porque usó frijoles con un solo objetivo. – sinuhepop

2

me encontré con este error en una manera muy estúpida

@Autowired 
// private Bean bean; 

public void myMethod() { 
    return; 
} 

lo que pasó es que les comentaba una línea por alguna razón ya la izquierda la anotación que hizo la primavera pensar que el método necesita ser autowired

18

Creo que se podría utilizar de primavera

@Lazy

anotación en uno de los campos autoconectados para romper la dependencia circular.

No estoy seguro de si esto funciona/existe en la versión Spring mencionada.

+2

Esto lo arregló para mí. ¡Gracias! – codematix

+0

¡Para mí asigna el frijol a la Excepción y continúa! –

Cuestiones relacionadas