2013-04-12 41 views
5

Jestem nowy na @Schedule adnotacji w J2EE6parametry dynamiczne dla metody @Schedule w EJB 3.x

Chcę uruchomić zadanie przy użyciu EJB 3.x z GlassFish 3.1.

javax.ejb.Schedule wydaje się być dobrym wyborem dla nas, więc możemy myśleć o naszym niestandardowym czasie coś takiego:

@Singleton 
public class CustomTimer { 
    @EJB 
    SettingsFacade settingsFacade; 

    @Schedule(second="someSecondParameter", minute="someMinuteParameter",hour="someHourParameter", persistent=false) 
    public void executeTimer(){ 
     //Code executing something against database using the settingsFacade 
    } 
} 

Tutaj chcemy parametry należy dostał z bazy danych, więc są one zmieniane co miesiąc. Jakieś czyste rozwiązanie tego?

+0

zobaczyć również http://stackoverflow.com/questions/2598712/how-to-parameterize-scheduledfixeddelay-with-spring-3-0-expression-language nie wiem, ale może o GlassFish język ekspresji + własność fasoli działa – gpilotino

+0

Drogi @ javadev, czy znajdziesz jakieś rozwiązanie dla harmonogramu parametrycznego? Jeśli znajdziesz, czy możesz rzucić okiem na moje pytanie: http://stackoverflow.com/questions/42242037/parameterize-ejb-scheduler-z-schedule-expression –

Odpowiedz

3

Nie, nie ma rozwiązania z @Schedule, ponieważ atrybuty adnotacji w ogóle powinny być kompilowanymi stałymi czasowymi.

Gdy potrzebna jest większa elastyczność, można użyć programmatic timers. Następnie należy zaimplementować pollingową bazę danych w celu zmiany konfiguracji i usunięcia istniejących oraz tworzenia nowych liczników czasu.

+0

Klasa ScheduleExpression nie działa poprawnie –

0

Cóż Należy utworzyć program Two Scheduler Uruchomiony zostanie jeden harmonogram, aby zaktualizować dane z bazy danych Na tej podstawie można utworzyć inny program planujący.

Ale za to trzeba to zrobić, co programowe. Możesz również zobaczyć zegary EJB dla tego samego, co pomoże ci w tym przypadku. który jest również oparty na adnotacjach.

0

Istnieje prosty sposób robienia tego. Chciałem czegoś, co nazywał proces każdego dnia, ale samo zadanie powinno być wykonywane losowo w ciągu tego samego dnia. Udało mi się to zrobić przez dodanie prostego wątku roboczego do uruchomienia po wywołaniu usługi zegara EJB. Potem uśpiłbym go przez losowy czas w ciągu tego dnia.

Poniższy kod jest przykładem usługi, która budzi się co 1 minutę i czeka na zakończenie wątku.

@Schedule(minute = "*/1", hour = "*", persistent = false) 
public void runEveryMinute() throws InterruptedException { 
    log.log(Level.INFO, "Scheduling for every minute .. now it's: " + new Date().toString()); 

    // Delay, in milliseconds before we interrupt adding a follower thread 
    //we can therefore garantee that it runs every day 
    long patience = 1000 * 5; 

    threadMessage("Starting forever alone no more thread"); 
    long startTime = System.currentTimeMillis(); 
    Thread t = new Thread(new MessageLoop()); 
    t.start(); 

    threadMessage("Waiting for new thread to finish"); 
    // loop until MessageLoop thread exits 
    while (t.isAlive()) { 
     threadMessage("Still waiting..."); 
     // Wait maximum of 1 second for MessageLoop thread to finish. 
     t.join(1000); 
     if (((System.currentTimeMillis() - startTime) > patience) 
       && t.isAlive()) { 
      threadMessage("Tired of waiting! Adding new followers now!"); 
      t.interrupt(); 
      // Shouldn't be long now -- wait indefinitely 
      t.join(); 
     } 
    } 
    threadMessage("Finally! You are not alone anymore!"); 

} 

// Display a message, preceded by 
// the name of the current thread 
static void threadMessage(String message) { 
    String threadName = Thread.currentThread().getName(); 
    System.out.format("%s: %s%n", threadName, message); 
} 

private static class MessageLoop implements Runnable { 

    public void run() { 
     String importantInfo[] = { 
      "A kid will eat ivy too" 
     }; 
     try { 
      for (int i = 0; 
        i < importantInfo.length; 
        i++) { 
       // Pause for 4 seconds 
       int max = 10; 
       int min = 2; 
       int randomTimer = 0 + (int) (Math.random() * ((max - min) + 1)); 
       Thread.sleep(randomTimer * 1000); 
       // Print a message 
       threadMessage(importantInfo[i]); 
      } 
     } catch (InterruptedException e) { 
      threadMessage("Patience is not a virtue! Thread stopping for now!"); 
     } 
    } 
} 
4
 
@Singleton 
@Startup 
public class ScheduleTimerService { 

    @Resource private TimerService timerService; 

    public void setTimerService(TimerService timerService) {this.timerService = timerService; } 

    @PostConstruct 
    private void postConstruct() { 
     timerService.createCalendarTimer(createSchedule()); 
    } 

    @Timeout 
    public void timerTimeout(Timer timer) { 
      Add your code here to be called when scheduling is reached... 
      in this example: 01h:30m every day ;-) 
    } 

    private ScheduleExpression createSchedule(){ 

     ScheduleExpression expression = new ScheduleExpression(); 
     expression.dayOfWeek("Sun,Mon,Tue,Wed,Thu,Fri,Sat");  
     expression.hour("01"); 
     expression.minute("30"); 

     return expression; 
    } 
} 
+0

Dziękuję @ Sólon Soares Mam dwa pytania: 1-Jak ustawić harmonogram, aby zadzwonić przy starcie? , 2- To, co jest równoważne @Schedule (second = "1", minute = "\ */5", hour = "\ *", persistent = false), Zmień swój kod, aby działał przy uruchomieniu. –

+1

Hi @ H.Aqjn, 1) Uruchamianie następuje po uruchomieniu jboss lub innego serwera aplikacji. Zobacz adnotację "@Startup" nad deklaracją klasy nazwy. Aplikacja serwera tworzy timer programowania "@PostContruct". Tak więc po osiągnięciu timera wywołuje metodę opisaną przez "@Timeout". Dlatego, gdy nastąpi zmiana timera, należy ponownie załadować pakiet na serwer aplikacji (ucho, wojna lub inny format pakietu). Klasa Expression akceptuje te same parametry adnotacji. –

+0

Drogi @ Sólon Soares, proszę spojrzeć na moje pytanie: http://stackoverflow.com/questions/42242037/parameterize-ejb-scheduler-with-schedule-expression –