Spring - Générer par programme un ensemble de haricots
J'ai un Dropwizard application qui doit générer une douzaine de haricots pour chacun des configs dans une liste de configuration. Des choses comme des contrôles de santé, le quartz, les planificateurs, etc.
Quelque chose comme ceci:
@Component
class MyModule {
@Inject
private MyConfiguration configuration;
@Bean
@Lazy
public QuartzModule quartzModule() {
return new QuartzModule(quartzConfiguration());
}
@Bean
@Lazy
public QuartzConfiguration quartzConfiguration() {
return this.configuration.getQuartzConfiguration();
}
@Bean
@Lazy
public HealthCheck healthCheck() throws SchedulerException {
return this.quartzModule().quartzHealthCheck();
}
}
J'ai plusieurs instances de MyConfiguration qui doivent tous être les haricots de ce genre.
Droit maintenant, je dois copier et coller ces définitions et de les renommer pour chaque nouvelle configuration.
Je peux en quelque sorte itérer sur ma configuration de classes et de générer un ensemble de haricot définitions pour chacun?
Je serait bien, avec un sous-classement de la solution ou tout autre type de sécurité sans me faire de copier et de coller le même code et de renommer les méthodes jamais le temps que j'ai à ajouter un nouveau service.
EDIT: je dois ajouter que j'ai d'autres composants qui dépendent de ces haricots (ils injectent Collection<HealthCheck>
par exemple.)
source d'informationauteur noah
Vous devez vous connecter pour publier un commentaire.
Si vous avez besoin de déclarer de nouveaux haricots à la volée et de les injecter dans le Printemps du contexte de l'application comme si ils étaient juste des haricots communs, ce qui signifie qu'ils doivent être soumis à l'utilisation de proxy, le post-traitement, etc, c'est à dire qu'ils doivent être soumis à des beans Spring cycle de vie.
Veuillez voir
BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()
méthode la documentation javadoc. C'est exactement ce que vous êtes dans le besoin, car il vous permet de modifier le Printemps du contexte de l'application la normale après les haricots définitions ont été chargés mais avant tout de haricot a été instancié.Ce déclare les haricots que vous avez besoin et leur injecte dans le Ressort du contexte de l'application, un ensemble de haricots pour chaque configuration. Vous devez compter sur certains modèle de nommage et puis autowire vos haricots par nom où c'est nécessaire:
Notes:
Si vous passez par la lecture de la configuration des noms manuellement à partir d'un fichier, utilisez le Printemps
ClassPathResource.getInputStream()
.Si vous passez par la numérisation de l'classpath par vous-même, je vous recommande fortement d'utiliser l'incroyable Les réflexions de la bibliothèque.
Vous devez régler manuellement toutes les propriétés et les dépendances pour chaque bean définition. Chaque bean définition est indépendante de l'autre bean définitions, c'est à dire vous ne pouvez pas les réutiliser, de les mettre l'un dans l'autre, etc. Pensez à eux comme si vous étiez en déclarant les haricots à l'ancienne XML.
Vérifier BeanDefinitionBuilder javadoc et GenericBeanDefinition javadoc pour plus de détails.
Vous devriez être en mesure de faire quelque chose comme ceci:
Juste élargissement sur Michaś réponse - sa solution fonctionne si je l'ai configuré comme ceci:
Une chose à noter est que je suis de la création de la coutume des haricots en tant qu'attributs de la classe de configuration et initialisation dans le @PostConstruct méthode. De cette façon, j'ai l'objet enregistré comme un haricot (donc @Autowire et @Inject fonctionne comme prévu) et que je puisse ensuite utiliser la même instance dans le constructeur d'injection pour les haricots qui en ont besoin. L'attribut de visibilité est protégé, de sorte que les sous-classes peuvent utiliser les objets créés.
Que l'instance que nous détenons et qui n'est en fait pas le Printemps proxy, certains problèmes peuvent se produire (des aspects qui ne sont pas de tir etc.). Il peut effectivement être une bonne idée à récupérer le haricot après l'inscription, comme dans:
Je vais puce d'ici. D'autres ont mentionné que vous avez besoin pour créer un bean, dans lequel la config est injecté.
Que bean va ensuite utiliser votre config pour créer d'autres haricots et les insérer dans le contexte (que vous aurez également besoin d'injecter dans une forme ou une autre).
Ce que je ne pense pas que quelqu'un d'autre a ramassé sur, c'est que vous avez dit, d'autres haricots dépendent de ces créé dynamiquement les haricots.
Cela signifie que votre dynamique de haricots usine doit être instancié avant la charge des haricots. Vous pouvez le faire (dans les annotations du monde) à l'aide de
Que pour ce type d'objet de votre habile bean factory est, d'autres ont recommandé de meilleures façons de le faire.
Mais si je me souviens correctement, vous pouvez réellement faire quelque chose comme cela dans l'ancien ressort 2 monde :
..
Vous avez besoin pour créer une configuration de base de la classe qui est prolongée par tous vos
Configuration
classes. Ensuite, vous pouvez parcourir toutes les classes de configuration comme suit:La "meilleure" approche que je pouvais venir a été à l'emballage de tous mes Quartz de configuration et des planificateurs en 1 uber de haricots et de fil tout ça manuellement, puis refactoriser le code pour travailler avec l'uber interface bean.
L'uber bean crée tous les objets que j'ai besoin de son PostConstruct et met en œuvre ApplicationContextAware de sorte qu'il peut auto-fil. Ce n'est pas idéal, mais c'était le mieux que je pouvais venir.
Printemps n'est tout simplement pas une bonne façon d'ajouter dynamiquement des haricots dans une typesafe.