2012-03-22 17 views
10

prototipo He una clase llamada barra con la siguiente anotación: @Configurable(autowire = Autowire.BY_TYPE)Autowire primavera y el alcance

En un miembro privado que tengo la siguiente anotación:

@Autowired(required = true) 
private Foo foo; 

En la configuración de la primavera tengo un grano de la clase Foo. Si el grano se define con scope="prototype" no funciona y me da la siguiente excepción:

NoSuchBeanDefinitionException: No coincidencia de frijol de tipo Foo encontró para la dependencia: esperar al menos 1 frijol, que califica como candidato para este Autowire dependencia

Una vez que cambio el alcance del frijol inyectado a "singleton" funciona bien.

¿No se permite el cableado automático del prototipo de frijol encuadrado?

¿Hay alguna solución (además de obtener el bean manualmente)?

Gracias de antemano, Avner

+0

Relacionados: http://stackoverflow.com/questions/27776672/spring-protype-scope-behaviour/27782040#27782040 –

Respuesta

9

Los siguientes enlaces proporcionan soluciones alternativas para este tipo de escenarios:

  1. http://whyjava.wordpress.com/2010/10/30/spring-scoped-proxy-beans-an-alternative-to-method-injection/
  2. http://benkiew.wordpress.com/2012/04/22/spring-2-5-x-create-prototype-instances-from-code/

el primer eslabón habla de la adición de Foo:

@Component 
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS, value = "prototype") 
class Foo 

lo que provocará una nueva instancia cada llamada.

+0

Es bueno lo que has escrito, pero sería mejor si simplemente escribes que configurarlo con proxy es obligatorio :) – tomekK

+0

Solo las respuestas del enlace son malas, ¿qué pasará si los enlaces dados desaparecen? –

-1

Si el alcance de frijol inyectado es 'Singleton', la misma instancia de la semilla será auto-cable. Si el alcance del bean inyectado es 'prototipo', se creará una nueva instancia como parte del proceso de autoenlace.

Qué versión de Spring está utilizando y también adjunte spring-context.xml para más detalles.

+1

Soy consciente de las diferencias entre el prototipo y el singleton, simplemente no entiendo por qué debería el alcance del frijol tiene influencia en el auto-cableado. Estoy usando la primavera 3. –

0

Creo que es el problema el prototipo/singleton declarado en su xml para ese bean.

¿No se permite el cableado automático del prototipo de bean con ámbito?

Creo que no está permitido. La lógica es si está permitido, entonces cada vez que use esa clase, necesita reinstalar ese bean siempre como su campo. Lo cual es extraño especialmente si la clase en la que este bean está autoconectado como campo es un singleton en sí mismo.

¿hay alguna solución (además de obtener el bean manualmente)?

Simplemente intente eliminar el atributo de ámbito, porque si se trata de un atributo de prototipo, no se recuperará. Si esos beans (servicios y DAO) se declaran en su applicationContext, simplemente deje que la anotación de autowire lo obtenga como singleton, ya que por defecto los beans son singleton, lo que debería ser.

+0

Gracias por su respuesta, pero eliminar el atributo del alcance no arreglará mi código ya que todas las instancias de Bar compartirán la misma instancia de Foo que no es lo que necesito. Además, la instancia de Foo se debe instanciar una vez por creación/inyección de objetos Bar y no por uso de campo (según mi comprensión). –

+0

no sé si hay una alternativa para su diseño específico, dígame si existe. Pero en lo que se refiere al diseño, los frijoles deben usarse de forma apátrida, significa tener cuidado en sus campos, asegurarse de que los campos utilizados en esos frijoles no sean campos globales sino campos de métodos, de esta manera, incluso su singleton, usted ganó No se preocupe si es compartido por muchas clases ya que no se comparte ninguna variable global, porque es sin estado. – vine

-2

o simplemente puede usar el nuevo operador.

+1

Eso derrota por completo el propósito completo de DI y IOC. – csmckelvey