Intégration JSF de printemps: comment injecter un composant/service de printemps dans le bean géré par JSF?
je comprends qu'un bean managé fonctionne comme un contrôleur, parce que votre seule tâche est" lier " la couche de vue avec le modèle.
pour utiliser un haricot comme un haricot géré je dois déclarer @ManagedBean
annotation, faisant que je peux communiquer JSF avec haricot directement.
si je veux injecter un composant (à partir du printemps) dans ce canal managé, j'ai deux possibilités:
-
choisir la propriété dans ManagedBean (comme "BasicDAO dao") et déclarer
@ManagedProperty(#{"basicDAO"})
au-dessus de la propriété. En le faisant, j'injecte le haricot"basicDAO"
de Spring dans ManagedBean. -
a déclaré @Controller dans la classe ManagedBean, alors j'aurai
@ManagedBean
et@Controller
annotations, toutes ensemble. Et dans la propriété"BasicDAO dao"
je dois utiliser@Autowired
de printemps.
est-ce que ma compréhension est correcte?
3 réponses
il y a une autre façon d'utiliser les fèves gérées au printemps dans les fèves gérées par JSF en prolongeant simplement votre fève JSF de SpringBeanAutowiringSupport
et le printemps gérera l'injection de dépendance.
@ManagedBean // JSF-managed.
@ViewScoped // JSF-managed scope.
public class GoodBean extends SpringBeanAutowiringSupport {
@Autowired
private SpringBeanClass springBeanName; // No setter required.
// springBeanName is now available.
}
@ManagedBean
vs @Controller
tout d'abord, vous devez choisir un cadre pour gérer vos haricots. Vous devez choisir JSF ou Spring (ou CDI) pour gérer vos haricots. Alors que les travaux suivants, il est fondamentalement faux:
@ManagedBean // JSF-managed.
@Controller // Spring-managed.
public class BadBean {}
vous vous retrouvez avec deux deux instances complètement distinctes de la même classe de haricots gérés, l'une gérée par JSF et l'autre gérée d'ici le Printemps. Il n'est pas évident de savoir lequel des deux en fait serait utilisé dans EL lorsque vous le mentionnez comme #{someBean}
. Si vous avez le SpringBeanFacesELResolver
enregistré dans faces-config.xml
, alors ce serait le ressort-géré, pas le JSF-géré. Si vous ne l'avez pas, ce sera celui géré par le JSF.
aussi, lorsque vous déclarez un champ d'application spécifique géré par JSF, tel que @RequestScoped
, @ViewScoped
, @SessionScoped
ou @ApplicationScoped
du paquet javax.faces.*
, il ne sera reconnu et utilisé que par @ManagedBean
. Il ne sera pas compris par @Controller
comme il attend sa propre annotation @Scope
. Ceci vaut par défaut pour singleton (application scope) en cas d'absence.
@ManagedBean // JSF-managed.
@ViewScoped // JSF-managed scope.
@Controller // Spring-managed (without own scope, so actually becomes a singleton).
public class BadBean {}
quand vous faites référence à la fève ci-dessus via #{someBean}
, il retournerait l'application gérée au printemps scoped bean, pas le JSF-managed view scoped bean.
@ManagedProperty
vs @Autowired
le @ManagedProperty
spécifique au JSF ne fonctionne que pour les haricots gérés par le JSF, c'est-à-dire lorsque vous utilisez @ManagedBean
. Le @Autowired
spécifique au printemps ne fonctionne que pour les haricots à gestion printanière, c'est-à-dire lorsqu'on utilise le @Controller
. Les approches ci-dessous sont de moins en moins équivalentes et ne peuvent pas être mélangées:
@ManagedBean // JSF-managed.
@RequestScoped // JSF-managed scope.
public class GoodBean {
@ManagedProperty("#{springBeanName}")
private SpringBeanClass springBeanName; // Setter required.
}
@Component // Spring-managed.
@Scope("request") // Spring-managed scope.
public class GoodBean {
@Autowired
private SpringBeanClass springBeanName; // No setter required.
}
notez que lorsque vous avez le SpringBeanFacesELResolver
enregistré dans faces-config.xml
que par le javadoc ,
<application>
...
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
et ainsi vous pouvez faire référence à des haricots avec gestion de printemps dans EL via #{springBeanName}
, alors vous pouvez simplement les faire référence dans @ManagedProperty
aussi, car il fixe fondamentalement le résultat évalué de L'expression donnée EL. Dans l'autre sens, injecter une fève gérée par JSF via @Autowired
, n'est en aucun cas supporté. Vous pouvez cependant utiliser @Autowired
dans une FJB gérée lorsque vous enregistrez manuellement le JSF instance bean gérée au printemps contexte autowinable comme ci-dessous. Voir aussi comment intégrer JSF 2 et Spring 3 (ou Spring 4) bien pour le truc.
@ManagedBean // JSF-managed.
@ViewScoped // JSF-managed scope.
public class GoodBean implements Serializable {
@Autowired
private SpringBeanClass springBeanName; // No setter required.
@PostConstruct
private void init() {
FacesContextUtils
.getRequiredWebApplicationContext(FacesContext.getCurrentInstance())
.getAutowireCapableBeanFactory().autowireBean(this);
// springBeanName is now available.
}
}
@XxxScoped
vs @Scope
Printemps @Scope
a un support limité pour le JSF étendues. Il n'y a pas d'équivalent pour le @ViewScoped
de JSF . En gros, soit tu ramènes tes propres lunettes, soit tu t'en tiens à l'enregistrement manuel. le JSF a géré l'instance bean au printemps dans un contexte autowinable comme indiqué ci-dessus.
et, de l'autre côté, Spring WebFlow a été repris dans JSF 2.2 via une nouvelle annotation @FlowScoped
. Donc, si vous êtes déjà sur JSF 2.2, vous n'avez pas nécessairement besoin d'utiliser Spring WebFlow si vous voulez uniquement le débitmètre.
CDI - essayer d'unifier tous les
depuis Java EE 6, le CDI est proposé comme alternative standard au Spring DI. Il a respectivement @Named
et @Inject
annotations pour ceci et aussi son propre ensemble de portées. Je ne sais pas comment il interagit avec le printemps car je n'utilise pas le printemps, mais @Inject
fonctionne à l'intérieur d'un @ManagedBean
, et @ManagedProperty
à l'intérieur d'un @ManagedBean
peut faire référence à un @Named
haricot. D'autre part, @ManagedProperty
ne fonctionne pas à l'intérieur d'un @Named
bean.
L'Objectif du CDI est d'unifier toutes les fèves différentes cadres de gestion en une seule spécification/interface. Le printemps aurait pu être une mise en œuvre complète du CDI, mais ils ont choisi de ne l'appliquer que partiellement (seul le JSR-330 javax.inject.*
est soutenu, mais pas le JSR-299 javax.enterprise.context.*
). Voir aussi Printemps de soutien CDI? et ce tutoriel .
JSF sera transféré au CDI pour la gestion des haricots et déprécier @ManagedBean
et amis dans une version future.
voir aussi:
la façon la plus simple de le faire est par XML. J'ai utilisé @Component
dans déjà fait JSF géré bean mais @Autowired
n'a pas fonctionné parce que géré bean était déjà là dans les visages-config.XML. S'il est obligatoire de conserver cette définition de fève gérée avec sa propriété gérée dans le fichier xml, alors il est suggéré d'ajouter la fève de printemps comme une autre propriété gérée à l'intérieur de l'étiquette de fève gérée. Ici le haricot de printemps est là défini dans la config de printemps.xml(peut être autowired somewhere alternativement.) veuillez vous référer
https://stackoverflow.com/a/19904591/5620851
édité par moi. Je suggère soit de le mettre en œuvre tout à fait par annotation @Managed et @Component ou via xml pour les deux.