2016-11-02 3 views
0

Ich habe einige Scheduler-Aufgaben, die UserInfoServiceExecutor, AdminInfoServiceExecutor-Dienste für jede Stunde auslösen (beide Dienste starten zur selben Zeit).Erzeugt der Frühling ein neues Objekt für autowired Felder?

Das Problem ist, diese Dienste mit LoggerService und LoggerService Suchmethode dauert fast 5 Minuten zu vervollständigen (ich meine while-Schleife). Da Sie UserInfo-Logs suchen müssen, müssen Sie sich mit einem Benutzeraccount anmelden und um Admin-Logs zu erhalten, müssen Sie sich mit einem Admin-Account einloggen (es bedeutet, dass verschiedene sessionTokens zurückkommen),

Überschreibt AdminInfoServiceExecutor UserInfoServiceExecutor sessionToken, wenn es danach startet?

@Service 
public class UserInfoServiceExecutor { 
    @Autowired 
    private LoggerService loggerService; 

    public void saveUserInfos(){ 
     loggerService.loginAndSearch("userInfo"); 
    } 

} 

@Service 
public class AdminInfoServiceExecutor { 
    @Autowired 
    private LoggerService loggerService; 

    public void saveAdminInfos(){ 
     loggerService.loginAndSearch("adminInfo"); 
    } 

} 

@Service 
public class LoggerService{ 

    private String sessionToken; 

    public String loginAndSearch(String key){ 

     if(key.equals("userInfo")) 
      sessionToken = login(user); 

     if(key.equals("adminInfo")) 
      sessionToken = login(admin); 

     search(key); 

    } 

    public String search(String keyword){ 
     while(hasMoreResults){ 
      getResults(keyword, sessionToken); 
     } 
    } 
} 

EDIT:. I Standard-Frühling Rahmen verwende (Singleton)

Antwort

3

Ihre Frage auf den Umfang Ihrer primär LoggerService Bohne, so weit wie die Federbehälter betrifft, es befasst sich Mit dem Gültigkeitsbereich, mit dem Sie zum Zeitpunkt der Definition der Bean deklarieren, ist der Standardbereich von Spring Singleton.

So wie Sie nicht wie Scope erwähnt haben, wird es als Singleton Umfang verwaltet werden

Wie Sie sessionToken als Klassenmitglied, das es jede Chance, es immer außer Kraft gesetzt ist, können Sie hier mit Synchronisation zu tun haben .

Hinweis: Synchronblock oder Synchron Methode funktioniert nur im Zuständigkeitsbereich der einzelnen JVM, falls Sie Ihren Code/Anwendung in gruppierten envioronment in verschiedenen JVMs implementieren diese Synchronisation Ansatz wird nicht funktionieren.

+0

Ja, ich verwende den Singleton-Bereich. Überschreibt AdminInfoServiceExecutor UserInfoServiceExecutor sessionToken, wenn es danach gestartet wird? – hellzone

1

Mit @Autoired Spring eine Referenz einer Frühlingsbohne injizieren. Nun, wenn der Umfang der jijjected Bean Singleton (Standardverhalten) ist, erhalten Sie die gleiche Instanz in jeder @Autowired Abhängigkeit und in allen Anfragen wird Ihr Service die gleiche Bean sehen. Wenn Ihre Spring-Bean in jeder @Autowired-Injektion als Prototyp-Bereich konfiguriert ist, wird eine neue Instanz der Spring-Bean injiziert, aber selbst in diesem Fall ist die Bean in jedem Fall derselbe. Gesagt, dass, weil in Ihrem Fall Sie eine Statebohne und nicht eine Staatenlose Bohne benötigen, Pheraps besser ein "Domain-Objekt" und nicht eine Frühlingsbohne verwenden werden. Ich möchte sagen, dass Sie einen wichtigen pojo verwenden können, der mit @Configurable annotiert ist, und ein neues Objekt in jeder Anfrage erstellen und ein neues Objekt für Ihre Propose verwenden. Mit @Configurable auf dem cofigurable Objekt und @EnableAspectJAutoProxy @EnableSpringConfigured @EnableLoadTimeWeaving in Ihrem configuraion

Ich hoffe, dass es Sie können

bearbeiten helfen:

Ich habe mein eigenes Open-Source-Projekt PhoneBoock (https://github.com/mrFlick72/phonebook/tree/master/phonebook-java-config) und Darin hatte ich ein ähnliches Problem. Ich hatte einen Erbauer von PhoneBookUser, der mein Benutzer hatte das passowrd, das mit einem Frühling Sicherheit PasswordEncoder beschriftet wurde. Zu Beginn hatte ich eine Singleton-Bean, die den PhoneBookUser PhoneBookUserBuilder baute, aber unglücklicherweise ein Singleton war, wenn zwei Benutzer eine neue Entität im Sing-up-Prozess erstellten, hatte ich eine interleeving ov-Interaktion, die die Daten beschädigen könnte.Für lösen dieses Problem, das ich meinen Code mit einem PhoneBookUserBuilder

@Configurable public class Refactoring

mit @Configurable kann ich ein neues Objekt mit neuen Betreiber und Nutzen von DI der Feder schaffen für die PasswordEncoder injizieren. Dieser Ansatz löste mein Problem. Ich kann vorschlagen, darüber nachzudenken, kann Ihnen wahrscheinlich helfen.

+0

Wenn ich mein sessionToken in lokale Variable ändere Löst es das Problem? – hellzone

+0

Ich denke über Nein, aber ich bearbeite meine Answare mit meiner Erfahrung mit einem ähnlichen Problem –

0

Ja, in diesem Fall, weil Sie eine Instanz der LoggerService-Bean haben. Normalerweise verfügen Sie nicht über stateful services. Konvertieren Sie daher das sessionToken-Feld in eine lokale Variable, wenn Sie diesen Status nicht zwischen Ihren anderen Spring-Beans freigeben möchten.

Verwandte Themen