Comment créer une demande d'étendue de haricot au moment de l'exécution avec le printemps
J'ai un printemps de l'application et que vous souhaitez créer un haricot au moment de l'exécution, conformément à la demande de l'injecter dans une autre classe, tout comme @Producer
pour le CDI.
Mon haricot est juste un simple POJO:
public class UserDetails {
private String name;
//getter /setter ...
public UserDetails(String name) {
this.name = name;
}
}
Le producteur de la classe ressemble à ceci:
@Configuration
public class UserFactory {
@Bean
@Scope("request")
public UserDetails createUserDetails() {
//this method should be called on every request
String name = SecurityContextHolder.getContext()
.getAuthentication().getPrincipal(); //get some user details, just an example (I am aware of Principal)
//construct a complex user details object here
return new UserDetails(name)
}
}
Et c'est la classe où l' UserDetails
instance doit être injecté:
@RestController
@RequestMapping(value = "/api/something")
public class MyResource {
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
public List<String> getSomething(UserDetails userDetails) {
//the userdetails should be injected here per request, some annotations missing?
//do something
}
}
Le problème, c'est que le Printemps se plaint au moment de l'exécution sur les pas de constructeur par défaut (bien sûr).
Failed to instantiate [UserDetails]: No default constructor found
Mais c'est prévu et je veux appeler mon propre usine de le laisser gérer l'Instanciation.
Comment puis-je y parvenir? Pourquoi est - UserFactory
jamais appelé?
- Printemps version utilisez-vous?
- J'utilise la version
4.2.5.RELEASE
- Vous n'êtes pas à l'injection d'une portée de haricot... Vous êtes tout simplement la création d'une nouvelle instance, ou le printemps fait pour vous. Si vous voulez une étendue de proxy, vous devez
@Autowire
dans votre contrôleur.
Vous devez vous connecter pour publier un commentaire.
Fondamentalement, vous n'utilisez pas votre portée proxy. Vous ne pouvez pas injecter une étendue de proxy dans une méthode, vous avez de l'injecter dans votre contrôleur.
Cela conduira à ressort essayant de créer une nouvelle instance de
UserDetails
par la réflexion, il ne sera pas injecter votre portée bean. Par conséquent, il se plaint du fait que vous avez besoin d'un défaut, aucun des arguments du constructeur.Au lieu de ce que vous devez faire est de fil de la dépendance dans votre contrôleur, au lieu de la méthode de contrôleur.
L'idée est que le
UserDetails
est une étendue de proxy et lorsqu'il est utilisé utilisera soit déjà présent objet ou d'en créer un nouveau, basé sur la@Bean
méthode.Additonally, le
@Scope
annotation dans leUserFactory
doit être modifié comme suit dans l'ordre de travail:Vous essayez d'injecter un la portée de la requête bean sur un singleton bean.
Vous devez utiliser un proxy pour le
UserDetails
ScopedProxyMode.TARGET_CLASS
que vous n'êtes pas en utilisant l'interface pourUserDetails
.Vous avez besoin d'un constructeur sans arguments dans la classe
UserDetails
.null
. Cela signifie que leUserFactory
est toujours pas appelé.