43 votes

Session de printemps étendue de haricots (contrôleurs) et des références à des services, en termes de sérialisation

  • un cas standard, - vous disposez d'un contrôleur (@Controller) avec @Scope("session").
  • les classes les mettre dans la session sont généralement appelés à mettre en œuvre Serializable , de sorte qu'ils peuvent être stockés physiquement dans le cas où le serveur est redémarré, par exemple
  • Si le contrôleur implémente Serializable, cela signifie que tous les services (autres beans spring), il se réfère également être sérialisé. Ils sont souvent les procurations, avec des références à des gestionnaires de transaction, l'entité gestionnaire d'usines, etc.
  • Il n'est pas rare que certaines service de, ou même contrôleur, maintenir une référence à l' ApplicationContext, par la mise en œuvre de ApplicationContextAware, donc cela peut effectivement dire que l'ensemble du contexte est sérialisé. Et étant donné qu'il détient de nombreuses connexions à - dire des choses qui ne sont pas sérialisables par l'idée, il sera restauré à la corruption de l'état.

Jusqu'à présent, j'ai surtout fait abstraction de ces questions. Récemment, j'ai pensé à déclarer toutes mes dépendances spring transient et les ramener en readResolve() par la statique des classes d'utilitaire WebApplicationContextUtils et maintenez-la demande/ServletContext en ThreadLocal. C'est fastidieux, mais elle garantit que, lorsque l'objet est désérialisé, ses dépendances seront "up to date" avec l' actuel contexte de l'application.

Est-il une pratique acceptée pour cela, ou toutes les lignes directrices pour la sérialisation des parties du printemps contexte.

Notez que dans le JSF, géré haricots (~contrôleurs) sont dynamiques (à la différence de l'action à base de frameworks web). Alors peut-être que ma question plus JSF, que pour spring-mvc.

19voto

Hans Westerbeek Points 2668

Dans cette présentation (environ 1:14) le président dit que ce problème est résolu dans le printemps 3.0 en fournissant un proxy de non sérialisable les fèves, qui obtient une instance de l' actuel contexte de l'application (sur la désérialisation)

7voto

laher Points 4882

Je m'attends à portée de contrôleurs comme "singleton", à savoir une fois par application, plutôt que dans la session.

La Session de la portée est généralement utilisé plus pour le stockage par utilisateur ou par des fonctions utilisateur.

Normalement, je viens de magasin de l'utilisateur de l'objet dans la session, et peut-être quelques fèves utilisées pour l'authentification ou tel. C'est tout.

Prendre un coup d'oeil au printemps docs pour la configuration des données de l'utilisateur dans la session, à l'aide d'un aop proxy:

http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-scopes-other-injection

Espère que ça aide

7voto

meriton Points 30447

Il semble que la générosité n'a pas attiré une seule réponse, donc je vais documenter ma compréhension limitée:

@Configuration
public class SpringConfig {

    @Bean 
    @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS) 
    MyService myService() {
        return new MyService();
    }

    @Bean
    @Scope("request")
    public IndexBean indexBean() {
        return new IndexBean();
    }

    @Bean
    @Scope("request")
    public DetailBean detailBean() {
        return new DetailBean();
    }
}

public class IndexBean implements Serializable {

    @Inject MyService myService;

    public void doSomething() {
        myService.sayHello();
    }
}

public class MyService {
    public void sayHello() {
        System.out.println("Hello World!");
    }
}

Le printemps sera donc pas injecter le nu MyService en IndexBean, mais un serializable proxy pour elle. (Je l'ai testé, et il a travaillé).

Toutefois, le printemps de la documentation écrit:

Vous n'avez pas besoin d'utiliser l' <aop:scoped-proxy/> en conjonction avec des haricots qui sont limités en tant que singletons ou prototypes. Si vous essayez de créer une étendue de proxy pour un singleton bean, l' BeanCreationException est élevé.

Au moins lors de l'utilisation de java en fonction de la configuration, de la fève et de sa procuration peut être instancié très bien, c'est à dire aucune Exception n'est levée. Cependant, il semble à l'aide de l'étendue des procurations pour atteindre serializability n'est pas l'usage prévu de ces procurations. J'ai peur de Printemps peut fixer que le "bug" et d'empêcher la création de l'étendue de procurations par Java en fonction de la configuration, trop.

Aussi, il y a une limitation: Le nom de la classe proxy est différent après le redémarrage de l'application web (parce que le nom de la classe proxy est basé sur le hashcode de l'avis qui est utilisé pour le construire, qui à son tour dépend de la hashCode d'un intercepteur de la classe de l'objet. Classe.hashCode ne pas remplacer l'Objet.hashCode, ce qui n'est pas stable entre les redémarrages). Par conséquent, la sérialisé sessions ne peuvent pas être utilisés par d'autres machines ou entre les redémarrages.

2voto

Thomas Kessler Points 203

J'ai récemment combiné JSF avec le Printemps. J'utilise RichFaces et l' @KeepAlive la fonction qui sérialise le JSF bean sauvegarde de la page. Il y a deux façons j'ai obtenu ce travail.

1) Utiliser @Component("session") sur le JSF backing bean

2) Obtenir le haricot de la ELContext quand vous en avez besoin, quelque chose comme ceci:

@SuppressWarnings("unchecked")
public static <T> T  getBean(String beanName) {
    return (T) FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(FacesContext.getCurrentInstance().getELContext(), null, beanName);
}

2voto

user1159790 Points 30

Après avoir essayé toutes les différentes variantes suggérées tout ce que j'avais à faire était d'ajouter de l'aop:l'étendue de proxy de mon haricot définition et il a commencé à travailler.

<bean id="securityService"
    class="xxx.customer.engagement.service.impl.SecurityContextServiceImpl">
    <aop:scoped-proxy/>
    <property name="identityService" ref="identityService" />
</bean>

securityService est injecté dans mon managedbean qui est vue étendue. Cela semble bien fonctionner. En fonction de printemps de la documentation de ce qui est censé jeter un BeanCreationException depuis securityService est un singleton. Toutefois, cela ne semble pas se produire et il fonctionne très bien. Pas sûr de savoir si c'est un bug ou d'une quels sont les effets secondaires seraient.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X