web-dev-qa-db-ja.com

Springで@Scheduledメソッドが実行されないのはなぜですか?

Use @Scheduledアノテーションを使用しようとしているので少し困惑していますが、Springは私のメソッドを見つけていないようです。最終的に、@Scheduledアノテーションが付けられた私のメソッドは実行されません。

次の宣言を使用して、Springのタスクマジックを呼び出しました。

<beans> <!-- XMLNS, XSD declarations omitted for brevity -->

  <context:component-scan base-package="com.mypackage"/>

  <task:executor id="executor" pool-size="5"/>
  <task:scheduler id="scheduler" pool-size="5"/>
  <task:annotation-driven scheduler="scheduler" executor="executor"/>

</beans>

そして、次のようなインターフェイスがあります:

package com.mypackage;

public interface MyInterface {

    public void executePeriodically();
}

次のような対応する実装で:

package com.mypackage.impl;
// imports omitted for brevity

@Service
public class MyInterfaceImpl implements MyInterface {

    @Scheduled(cron = "0/5 * * * * ?")
    public void executePeriodically() {
        System.out.println("The time is now : " + new Date());
    }
}

予想される結果は、5秒ごとの時間を教えてくれるとてもうるさい小さな男がいるということです...しかし、実際にはまったく何も得られません。インターフェースメソッドとimplメソッドでアノテーションを試しましたが、何も変わらないようです。

ログに次の内容があるため、エグゼキューターとスケジューラーが初期化されていることは確かです。

INFO  - ThreadPoolTaskExecutor     - Initializing ExecutorService 
INFO  - XmlWebApplicationContext   - Bean 'executor' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO  - XmlWebApplicationContext   - Bean 'executor' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO  - ThreadPoolTaskScheduler    - Initializing ExecutorService  'scheduler'
INFO  - XmlWebApplicationContext   - Bean 'scheduler' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

私は、資格がないことについてのその線が関連するのか、それともニシンなのかわかりません。

現時点では、次のようにスケジュールされたタスクを宣言することで回避しています。

<task:scheduled-tasks>
  <task:scheduled ref="sourceDocumentManagerImpl" method="deleteOldDocuments" cron="0 0 * * * ?"/>
</task:scheduled-tasks>

これは完全に正常に機能しますが、そのメソッドに対する期待をコードで直接確認する方がはるかに便利なので、むしろアノテーションを使用します。誰が私が間違っているのか知っていますか?記録のために、私はSpring 3.0.4を使用しています

本当にありがとう!

25
stevevls

だから... AOPプロキシ上の@Scheduledアノテーションの発見に関係するSpring 3.0.x(少なくとも3.0.4と3.0.5)に問題があるように見えます。 @Scheduledメソッドをトランザクションアドバイスでラップするポイントカット宣言を取得しましたが、これが問題の根本のようです。アドバイスを削除すると、ジョブが実行されます。再び追加すると、Springは注釈付きメソッドのタスクの検索と作成に失敗します。

だから、私はSpringの人々にバグを報告するつもりです、そしてその間、私は自分のタスクを手動で宣言するのにこだわっています。

13
stevevls

「task:annotation-driven」を追加しますか?

<beans> <!-- XMLNS, XSD declarations omitted for brevity -->

  <context:component-scan base-package="com.mypackage"/>
  <task:annotation-driven/>
  <task:executor id="executor" pool-size="5"/>
  <task:scheduler id="scheduler" pool-size="5"/>
  <task:annotation-driven scheduler="scheduler" executor="executor"/>

</beans>

参照 http://howtodoinjava.com/2013/04/23/4-ways-to-schedule-tasks-in-spring-3-scheduled-example/

または

注釈駆動型タスク用のSpring @Configuration(非XML構成)

WebMvcConfigクラスに@EnableSchedulingを追加するだけです

@Configuration
@EnableWebMvc
@EnableAsync
@EnableScheduling
public class WebMvcConfig extends WebMvcConfigurerAdapter {
   /** Annotations config Stuff ... **/
}

参照 スプリングスケジューラーは機能しません

16
ahll

Spring 3.1.2を使用しているにもかかわらず、ApplicationContext.xmlにexecutorタグとschedulerタグを配置すると、同じ問題が発生します。私のプロジェクトには、春用の2つのxml構成ファイルがあります:

  1. applicationContext.xml
  2. dispatcher-servlet.xml

したがって、springが読み取る最後の構成ファイルに構成を移動してみてください。私の場合、設定をdispatcher-servlet.xmlに移動することで動作を開始します

ここに私の例があります:

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context" 
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">

    <bean id="config" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="location" value="/WEB-INF/configuration.properties" />
    </bean>

    <!-- To fix the problem with Unicode characters in ajax responses -->
    <bean class = "org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <array>
                <bean class = "org.springframework.http.converter.StringHttpMessageConverter">
                    <property name="supportedMediaTypes" value = "text/plain;charset=UTF-8" />
                </bean>
                <bean id="byteArrayMessageConverter" class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
            </array>
        </property>
    </bean>

    <!-- Hibernate Configuration
        p:driverClassName="com.mysql.jdbc.Driver"
        p:url="jdbc:mysql://localhost:3306/iss"
        p:username="root"
        p:password="root"
    -->
    <bean name="DataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
          p:driverClassName="org.postgresql.Driver"
          p:url="jdbc:postgresql://localhost:5432/iss"
          p:username="postgres"
          p:password=""

    />

    <!--<bean name="SessionFactory" class="org.springframework.orm.hibernate4.annotation.AnnotationSessionFactoryBean">-->
    <bean name="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource">
            <ref bean="DataSource" />
        </property>
        <property name="hibernateProperties">
            <props>
                <!--<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>-->
                <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.show_sql">true</prop>
                <!--<prop key="hibernate.current_session_context_class">thread</prop>-->
                <!--<prop key="hibernate.current_session_context_class">managed</prop>-->
                <!--<prop key="hibernate.search.default.indexBase">/tmp/hibernate/indexes/</prop>-->
                <!--<prop key="hibernate.flushMode">AUTO</prop>-->
                <prop key="hibernate.connection.useUnicode">true</prop>
                <prop key="hibernate.connection.characterEncoding">UTF-8</prop>
                <prop key="hibernate.cache.use_second_level_cache">false</prop>
                <prop key="hibernate.cache.use_query_cache">false</prop>
                <prop key="hibernate.connection.autocommit">false</prop>
            </props>
        </property>
        <property name="packagesToScan" value="iss.DB" />
    </bean>

    <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <mvc:interceptors>
        <bean class="org.springframework.orm.hibernate4.support.OpenSessionInViewInterceptor">
            <property name="sessionFactory" ref="sessionFactory" />
        </bean>
    </mvc:interceptors>

    <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>


<!-- in this file it wont work
        <task:executor id="myExecutor" pool-size="1" />
    <task:scheduler id="myScheduler" pool-size="1" />
    <task:annotation-driven 
        executor="myExecutor"
        scheduler="myScheduler"/>    
-->
</beans>

dispatcher-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
       http://www.springframework.org/schema/aop 
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-3.1.xsd
       http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd" 
       xmlns:context="http://www.springframework.org/schema/context">

    <bean class="org.springframework.web.servlet.mvc.support.AnnotationControllerTypePredicate"/>

    <context:component-scan base-package="iss"/>
    <context:component-scan base-package="com.hazhir"/>

    <!--Internationalization -->
    <bean id="messageSource"
          class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="iss.languages.text" />
    </bean>

    <bean id="localChangeInterseptor"
          class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
        <property name="paramName" value="language" />
    </bean>

    <bean id="localeResolver"
          class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
        <property name="defaultLocale" value="en_US" />
        <property name="cookieName" value="clientLanguage" />
        <property name="cookieMaxAge" value="99999999"/>
    </bean>

    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <property name="alwaysUseFullPath" value="true" />
        <property name="interceptors">
            <list>
                <ref bean="localChangeInterseptor" />
            </list>
        </property>
    </bean>

    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          p:prefix="/WEB-INF/jsp/"
          p:suffix=".jsp">
        <property name="exposeContextBeansAsAttributes" value="true" />
    </bean>

    <!-- Multipart form data -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="1000000000" />
    </bean>

    <context:annotation-config />

    <!-- here is a right place for such configuration
        -->
    <task:executor id="myExecutor" pool-size="1" />
    <task:scheduler id="myScheduler" pool-size="1" />
    <task:annotation-driven 
        executor="myExecutor"
        scheduler="myScheduler"/> 
</beans>

それが役に立てば幸い。

4
Hazhir

ApplicationContext.xmlにdefault-lazy-init = "false"を追加して修正しました。

<beans .....
    **default-lazy-init="false"**>
3
Aman Ghrera

私のセットアップから見える唯一の違い(これは機能します)は、私のクラスに@Componentではなく@Serviceという注釈が付けられていることです。その他の確認事項:

  • クラスパスに適切なjarファイルがあるかどうか(スプリングコンテキスト、私は思う)
  • ブレークポイントを設定し、実際に実行されていないかどうかを確認します
  • cron表現を再確認します(これについては常にドキュメントを参照してください)。または、機能するかどうかを確認するために、固定遅延を使用します
  • 3.0.5または最新の3.1スナップショットにアップグレードしてみてください。
2
Bozho

Context:component-scanのuse-default-filters = "false"を削除して解決します

 <context:component-scan base-package="com.XXXx" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

私の春バージョン3.2.3

1
user2416625

これはかなり古い質問ですが、これは引き続きGoogle検索結果に表示されるため、Spring 5で機能していたソリューションを追加しましょう。私にとっては、@Componentを持つクラスへ@Scheduled注釈付きメソッド。

0
nabeel

私は両方を追加して解決しました:

xmlns:task="http://www.springframework.org/schema/task"
xmlns:tx="http://www.springframework.org/schema/tx"

その後:

<!-- TASK -->
    <task:scheduler id="searchScheduler" pool-size="1"/>
    <task:executor id="searchExecutor" pool-size="1"/>
    <task:annotation-driven executor="searchExecutor"  scheduler="searchScheduler"/>

そして、applicationContext.xmlのbootomで:

<tx:annotation-driven/>
0
Mike