En utilisant Java Config de Spring, j'ai besoin d'acquérir / d'instancier un bean à portée prototype avec des arguments de constructeur qui ne peuvent être obtenus qu'au moment de l'exécution. Considérez l'exemple de code suivant (simplifié par souci de concision):
@Autowired
private ApplicationContext appCtx;
public void onRequest(Request request) {
//request is already validated
String name = request.getParameter("name");
Thing thing = appCtx.getBean(Thing.class, name);
//System.out.println(thing.getName()); //prints name
}
où la classe Thing est définie comme suit:
public class Thing {
private final String name;
@Autowired
private SomeComponent someComponent;
@Autowired
private AnotherComponent anotherComponent;
public Thing(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
Avis name
est final
: il ne peut être fourni par un constructeur, et garantit immuabilité. Les autres dépendances sont des dépendances spécifiques à l'implémentation de la Thing
classe et ne doivent pas être connues (étroitement liées à) l'implémentation du gestionnaire de requêtes.
Ce code fonctionne parfaitement avec la configuration Spring XML, par exemple:
<bean id="thing", class="com.whatever.Thing" scope="prototype">
<!-- other post-instantiation properties omitted -->
</bean>
Comment obtenir la même chose avec la configuration Java? Ce qui suit ne fonctionne pas avec Spring 3.x:
@Bean
@Scope("prototype")
public Thing thing(String name) {
return new Thing(name);
}
Maintenant, je pourrais créer une usine, par exemple:
public interface ThingFactory {
public Thing createThing(String name);
}
Mais cela va à l' encontre de l'intérêt d'utiliser Spring pour remplacer le modèle de conception ServiceLocator et Factory , ce qui serait idéal pour ce cas d'utilisation.
Si Spring Java Config pouvait faire cela, je pourrais éviter:
- définition d'une interface Factory
- définition d'une implémentation Factory
- rédaction de tests pour l'implémentation Factory
C'est une tonne de travail (relativement parlant) pour quelque chose d'aussi trivial que Spring prend déjà en charge via la configuration XML.
Thing
implémentation est en fait plus complexe et a des dépendances sur d'autres beans (je les ai juste omis par souci de concision). En tant que tel, je ne veux pas que l'implémentation du gestionnaire de requêtes les sache, car cela couplerait étroitement le gestionnaire aux API / beans dont il n'a pas besoin. Je mettrai à jour la question pour refléter votre (excellente) question.
@Qualifier
paramètres à un setter avec @Autowired
sur le setter lui-même.
@Bean
fonctionne. La @Bean
méthode est appelée avec les arguments appropriés que vous avez passés getBean(..)
.