2013-02-12 17 views
7

Pomyślałem, że adnotacje wiosenne powinny działać po wyjęciu z pudełka w środowisku Grails, ale w ogóle nie mogę go uruchomić. Próbowałem również metody afterProperties, która również nie działała.@PostConstruct nie działa po cichu w usłudze Grails

Czy ktoś może pomylić? Czy jest jakaś konfiguracja, którą muszę wykonać?

package dashboard 

import javax.annotation.PostConstruct 

class EmailJobSchedulerService 
{ 
    def grailsApplication 

    @PostConstruct 
    def init() { 
     def cronExpression = grailsApplication.config.emailAt8AmTrigger 
     println(cronExpression) 
     EmailSubscribersJob.schedule(cronExpression, new HashMap()) 
    } 
} 
+0

Adnotacja wdrożyć wiele ograniczeń (patrz http://docs.oracle.com/javase/7/docs/api/javax/annotation/PostConstruct.html). Czy one wszystkie mają zastosowanie? – lucke84

+0

@ lucke84 Po zmianie, aby anulować zgodnie z sugestią Iana, powinienem przestrzegać wszystkich ograniczeń. – willcodejavaforfood

+4

Kiedy należy się spodziewać wydrukowania cronExpression? Na początku serwera? Wydaje mi się, że jest to wywoływane, gdy wykonywane jest pierwsze wywołanie dowolnej z metod usługi, a nie podczas uruchamiania serwera. Sugeruję wywołanie metody dummy w bootstrapie tylko w celu potwierdzenia. – uchamp

Odpowiedz

14

Spróbuj zmienić ją

@PostConstruct 
void init() { 

(tj void zamiast def). Nie jestem pewien, czy Spring wyraźnie to wymusza, ale specification of @PostConstruct stwierdza, że ​​między innymi "Typ zwrotu metody MUSI być nieważny".

Edycja: komentarz uchamp jest poprawny, właśnie wypróbowałem ten sam test i rzeczywiście metoda o adnotacji @PostConstruct jest wywoływana tylko przy pierwszym użyciu komponentu Service bean i niekoniecznie natychmiast po uruchomieniu. Możesz dodać klasę usługi do klasy usługi, aby wymusić jej inicjalizację przy uruchomieniu. Wygląda na to, że nie jest to udokumentowane w podręczniku użytkownika, wydedukowałem go przez reading the code.

Należy zauważyć, że "użyty" w poprzednim paragrafie niekoniecznie oznacza, że ​​należy wywołać na nim metodę. Element bean usługi zostanie zainicjowany po raz pierwszy, gdy zostanie pobrany z kontekstu aplikacji, bezpośrednio lub z powodu automatycznego automareducji do innego inicjalizowanego komponentu bean. Na przykład wstrzykiwanie usługę do Bootstrap użyciu

def emailJobSchedulerService 

wystarczy, by odpalić metodę @PostConstruct, nie trzeba rzeczywiście wywołać dowolną z metod usługa jest z zamknięciem BootStrap.init. Podobnie, gdyby twoja usługa została wstrzyknięta do któregokolwiek kontrolera, to init uruchomiłby się po raz pierwszy, gdy jeden z tych kontrolerów obsłużyłby żądanie (każde żądanie, to nie musi być działanie, które wywołuje usługę).

+0

Wciąż nic. Doceń wysiłek :) – willcodejavaforfood

+1

@willcodejavaforfood zakładając, że dany plik '.groovy' jest w' grails-app/services', a nie 'src/groovy', to powinien już działać. Używałem tej samej sztuczki wiele razy. Należy jednak pamiętać, że GORM prawdopodobnie nie jest dostępny w czasie '@ PostConstruct'. Jeśli chcesz zrobić cokolwiek metodami GORM, prawdopodobnie będziesz musiał zdefiniować normalną metodę bez adnotacji i wywołać ją z BootStrap. –

+0

To jest dziwne.Stworzono nawet zupełnie nowy projekt, który również nie był wywoływany z linii poleceń i @PostConstruct. Nie potrzebuję do tego GORMa, po prostu zaplanuj moją pracę, która nie jest utrzymywana. – willcodejavaforfood

1

Wystarczy dodać na odpowiedź od @Ian - Z jakiegoś powodu miałem:

@PostConstruct 
private void init() { 

To również nie cicho i dał dziwne zachowanie. Rozwiązanie było usunięcie „prywatny”:

@PostConstruct 
void init() { 
Powiązane problemy