Bagaimana membuat parameter @Scheduled (fixedDelay) dengan bahasa ekspresi Spring 3.0?

125

Saat menggunakan kemampuan Spring 3.0 untuk membubuhi keterangan tugas terjadwal, saya ingin mengatur fixedDelayparameter sebagai dari file konfigurasi saya, alih-alih menghubungkannya dengan kabel ke dalam kelas tugas saya, seperti saat ini ...

@Scheduled(fixedDelay = 5000)
public void readLog() {
        ...
}

Sayangnya tampaknya dengan sarana Spring Expression Language (SpEL) @Valuemengembalikan objek String yang pada gilirannya tidak dapat otomatis kotak ke nilai yang panjang seperti yang dipersyaratkan oleh fixedDelayparameter.

ngeek
sumber

Jawaban:

26

Saya kira @Scheduledpenjelasannya tidak perlu dipertanyakan. Jadi mungkin solusi untuk Anda adalah menggunakan task-scheduledkonfigurasi XML. Mari kita perhatikan contoh ini (disalin dari Spring doc ):

<task:scheduled-tasks scheduler="myScheduler">
    <task:scheduled ref="someObject" method="readLog" 
               fixed-rate="#{YourConfigurationBean.stringValue}"/>
</task:scheduled-tasks>

... atau jika para pemain dari String ke Long tidak bekerja, sesuatu seperti ini akan:

<task:scheduled-tasks scheduler="myScheduler">
    <task:scheduled ref="someObject" method="readLog"
            fixed-rate="#{T(java.lang.Long).valueOf(YourConfigurationBean.stringValue)}"/>
</task:scheduled-tasks>

Sekali lagi, saya belum mencoba pengaturan ini, tapi saya harap ini bisa membantu Anda sedikit.

Grzegorz Oledzki
sumber
Terima kasih, konfigurasi XML berhasil. Saya agak terkejut bahwa anotasi itu tampaknya sangat terikat dengan nilai string, bagaimanapun, saya menggunakan cara old-school ;-)
ngeek
1
Apakah ada padanan Java untuk konfigurasi di atas?
amique
@Grzegorz Oledzki apa yang akan menjadi nilai "someObject" di bawah tag <task: dijadwalkan>. Jika controller memiliki lebih dari satu metode yang memerlukan penundaan tetap dan penundaan awal maka bagaimana itu akan ditangani?
Mohit Singh
422

Spring v3.2.2 telah menambahkan parameter String ke parameter 3 panjang asli untuk menangani ini. fixedDelayString, fixedRateStringdan initialDelayStringsekarang tersedia juga.

@Scheduled(fixedDelayString = "${my.fixed.delay.prop}")
public void readLog() {
        ...
}
Mark-A
sumber
3
@ Avi Jawaban ini muncul tiga tahun setelah pertanyaan OP. Pada saat pertanyaan (dan jawaban yang diterima) fitur ini tidak ada.
medveshonok117
@ medveshonok117 Mengerti. Terima kasih
Avi
51

Anda dapat menggunakan @Scheduledanotasi, tetapi bersama dengan cronparameter saja:

@Scheduled(cron = "${yourConfiguration.cronExpression}")

Interval 5 detik Anda dapat dinyatakan sebagai "*/5 * * * * *". Namun seperti yang saya mengerti Anda tidak dapat memberikan ketelitian kurang dari 1 detik.

kan
sumber
9
Ekspresi cron yang Anda perlihatkan setara dengan fixRate, yang berbeda dengan fixDelay
codebox
4

Di Spring Boot 2, kita dapat menggunakan Spring Expression Language (SpPL) untuk @Scheduledproperti anotasi:

@Scheduled(fixedRateString = "${fixed-rate.in.milliseconds}")
public void fixedRate() {
    // do something here
}

@Scheduled(fixedDelayString = "${fixed-delay.in.milliseconds}")
public void fixedDelay() {
    // do something here
}

@Scheduled(cron = "${cron.expression}")
public void cronExpression() {
    // do something here
}

The application.propertiesFile akan terlihat seperti ini:

fixed-rate.in.milliseconds=5000
fixed-delay.in.milliseconds=4000
cron.expression=0 15 5 * * FRI

Itu dia. Berikut ini adalah artikel yang menjelaskan penjadwalan tugas secara rinci.

attacomsian
sumber
1

Saya kira Anda dapat mengonversi nilainya sendiri dengan mendefinisikan kacang. Saya belum mencobanya , tetapi saya kira pendekatan yang mirip dengan yang berikut ini mungkin berguna bagi Anda:

<bean id="FixedDelayLongValue" class="java.lang.Long"
      factory-method="valueOf">
    <constructor-arg value="#{YourConfigurationBean.stringValue}"/>
</bean>

dimana:

<bean id="YourConfigurationBean" class="...">
         <property name="stringValue" value="5000"/>
</bean>
Grzegorz Oledzki
sumber
Terima kasih, itu kedengarannya seperti satu arah, tetapi jujur ​​saja saya berharap untuk solusi ("springish") yang lebih elegan :-)
ngeek
2
Sayangnya ini tidak akan berfungsi, karena atribut anotasi @Jadwal tetap fixedDelay membutuhkan konstanta (panjang) untuk ditugaskan.
ngeek
Ah, benar juga. Jadi saya kira Anda tidak dapat melakukannya dengan @Scheduledanotasi itu.
Grzegorz Oledzki