【Jakarta EE 12】Jakarta Concurrency 3.2 変更点まとめ


スケジュールされたメソッドの自動起動

javax.ejb.Schedule による EJBタイマーサービスに相当する機能を CDI に導入。

Jakarta Concurrency 3.1 における @Schedule

Jakarta Concurrency 3.1 では、@Schedule アノテーションが @AsynchronousrunAt 属性として指定された場合、スケジュールは非同期メソッドを実行するまでの時間を定義する。

@Asynchronous(runAt = {
    @Schedule(daysOfweek = DayOfWeek.WEDNESDAY, hours = 10, minutes = 30)
})
public CompletableFuture<String> attendLectureAndLab(String course) {
}

上記のメソッドは、スケジュールされた時刻に達しても、アプリケーションがメソッドを呼び出して手動でスケジュールを要求するまで実行されない。

アプリケーションの Startup イベントをオブザーブすることでアプリケーション起動時に自動的にスケジュールされるように記述することはできる。

@Asynchronous(runAt = @Schedule(cron = "30 8 * * SAT,SUN", zone = "America/Chicago"))
public void weekendsAtEightThirtyAM({@literal @}Observes Startup event) {
    System.out.println("Good morning. Today is " + ZonedDateTime.now());
}


Jakarta Concurrency 3.2 における @Schedule

Jakarta Concurrency 3.2 では以下のようにCDIビーンのメソッドに直接 @Schedule を付与可能となった(メソッドは 戻り値 void で、パラメータを取ることはできない)。

@ApplicationScoped
public class ScheduleBean {

   @Schedule(daysOfWeek = { DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY, DayOfWeek.FRIDAY },
             hours = 10, zone = "America/Chicago")
   public void monWedFriAt10() {
      System.out.println("Running at " + ZonedDateTime.now());
   }

}

前述の Startup イベントをオブザーブした場合と同様に動作する。

これにより javax.ejb.Schedule による EJBタイマーサービスに相当する機能が、CDI 上で jakarta.enterprise.concurrent.Schedule を介して提供される。


Lock アノテーションの追加

EJB の jakarta.ejb.Lock と同様な、CDI で利用可能な @Lock アノテーションの追加

@Lock 
@ApplicationScoped
class SharedService {

  @Lock(value = Lock.Type.READ, time = 1, unit = TimeUnit.SECONDS)  
  BigDecimal getAmount() {
    // ...it is safe to read the value concurrently
  }
}


MaxConcurrency アノテーションの追加

最大同時実行数を制限する @MaxConcurrency の追加。


@Asynchronous にアノテーションリテラルの追加

@Asynchronous に不足していたアノテーションリテラルの追加。

アノテーションリテラルは、CDIにおいてプログラムでBeanにアノテーションを追加する際に利用するもの。

@Documented
@Inherited
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
public @interface Asynchronous {
    // ...
    public static final class Literal extends AnnotationLiteral<Asynchronous> implements Asynchronous {
        private static final long serialVersionUID = 1L;
        public static final Literal INSTANCE = new Literal();
    }
}