web-dev-qa-db-fra.com

Ressort autowire et portée prototype

J'ai une classe nommée Bar avec l'annotation suivante: @Configurable(autowire = Autowire.BY_TYPE)

Sur un membre privé, j'ai l'annotation suivante:

@Autowired(required = true)
private Foo foo;

Dans la configuration de printemps, j'ai un haricot de classe Foo. Si le bean est défini avec scope="prototype", cela ne fonctionne pas et j'obtiens l'exception suivante:

NoSuchBeanDefinitionException: aucun bean correspondant du type Foo trouvé pour la dépendance: Attendu au moins 1 bean pouvant être considéré comme candidat autowire pour cette dépendance. 

Une fois que je change la portée du bean injecté en "singleton", cela fonctionne bien.

Le câblage automatique du prototype de haricot délimité n'est-il pas autorisé?

Existe-t-il une solution de contournement (en plus de l’obtention manuelle du bean)?

Merci d'avance, Avner

12
Avner Levy

Les liens suivants proposent des solutions alternatives pour de tels scénarios:

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

Le premier lien concerne l’ajout à Foo: 

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

Ce qui provoquera une nouvelle instance à chaque appel.

11
Avner Levy

Je crois que c'est le problème prototype/singleton déclaré dans votre code XML pour ce haricot est la question. 

Le câblage automatique du prototype de haricot délimité n'est-il pas autorisé?

Je pense que ce n'est pas permis. La logique est que si cela est autorisé, chaque fois que vous utilisez cette classe, il doit alors ré-instancier toujours ce bean en tant que champ. Ce qui est étrange surtout si la classe dans laquelle ce bean est automatiquement câblé comme un champ est un singleton lui-même.

y a-t-il une solution de contournement (à côté de la récupération manuelle du grain)?

Essayez simplement de supprimer l'attribut scope, car s'il s'agit d'un attribut prototype, il ne sera pas récupéré. Si ces beans (services et DAO) sont déclarés dans votre applicationContext, laissez simplement l'annotation autowire l'obtenir en singleton, car par défaut les beans sont singleton, comme il se doit.

0
vine