Spring没有检测@Scheduled Methods



我正在运行Spring 3.2.3。RELEASE和我在@Service装饰类中有几个方法,它们是计划任务,因此用@Scheduled注释装饰。

所有的Spring bean都在容器中被检测和实例化,但是@Scheduled注释永远不会被调用。

我有几个应用程序上下文,但是主文件如下所述:

  <?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:context="http://www.springframework.org/schema/context"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <import resource="classpath:core-properties.xml" />
    <import resource="classpath:core-datasource.xml" />
    <import resource="classpath:core-task-scheduler.xml" />
    <context:component-scan base-package="com.atlaschase.project.core">
        <context:exclude-filter type="regex"
            expression="com.atlaschase.project.core.services.jms.*" />
        <context:exclude-filter type="regex"
            expression="com.atlaschase.project.core.services.processor.*" />
        <context:exclude-filter type="regex"
            expression="com.atlaschase.project.core.services.remote.*" />
        <context:exclude-filter type="regex"
            expression="com.atlaschase.project.core.bootstrap.populators.*" />
    </context:component-scan>
    <bean id="bufferPopulator" class="com.atlaschase.project.core.services.jms.buffer.BufferPopulator"/>
    <bean id="eventBuffer" class="com.atlaschase.project.core.services.jms.buffer.EventBuffer"/>
    <bean id="processorEventHandler" class="com.atlaschase.project.core.services.jms.buffer.ProcessorEventHandler"/>

另一个重要文件导入为"core-task-scheduler.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:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
    <task:executor id="myExecutor" pool-size="1"/>
    <task:scheduler id="myScheduler" pool-size="5"/>
</beans>

最初,执行器引用(上面)是在主应用程序上下文中定义的,但在阅读了其他类似的问题已经以这种方式解决后,我将其作为导入分离出来。不幸的是,这并没有帮助。我还移动了导入声明,但这似乎没有效果。

在Spring应用程序上下文中直接声明计划的方法工作得很好——但是我非常热衷于使用注释。

下面是带注释的类:
**
 * Service that batches the saving of position updates into a periodically executed
 * process. 
 */
@Service
public class PositionAggregatorService {
    static Logger logger = Logger.getLogger(AircraftPositionAggregatorService.class);
    // The service will not execute within 1 minute of a previous batch attempt.
    // This paramater is updated by a message from another node indicating that
    // they are commencing a batch save of position updates.
    private DateTime blockingTime; 
    private Map<Long, List<Position>> positions;
    @Autowired
    private PositionDao positionDao;
    @Autowired
    private InternalPublisher internalEventPublisher;
    @PostConstruct
    private void initialise(){
        positions = new ConcurrentHashMap<Long, List<Position>>();
    }
    /*
     * Scheduled to execute every 10 minutes as long current time is not
     * before the blocking time threshold.
     * 
     * */
    @Scheduled(fixedRate=6000)
    public void batchSavePositionUpdates(){
        if(blockingTime != null){
            if(DateTime.now(DateTimeZone.UTC).isBefore(blockingTime)){
                return;
            }
        }
        PositionPersistStartedNotification started = new PositionPersistStartedNotification(DateTime.now(DateTimeZone.UTC), DateTime.now(DateTimeZone.UTC).plusMinutes(2));
        internalEventPublisher.publishPositionPersistStartedNotification(started);
        DateTime mostRecentUpdateTime = null;
        List<Position> positionsToSave = new ArrayList<Position>();
        for(Long flightId : positions.keySet()){
            List<Position> positionList = positions.get(flightId);
            for(Position position : positionList){
                if(mostRecentUpdateTime == null){
                    mostRecentUpdateTime = new DateTime(position.getTime());
                }
                else{
                    DateTime positionTime = new DateTime(position.getTime());
                    if(positionTime.isAfter(mostRecentUpdateTime)){
                        mostRecentUpdateTime = positionTime;
                    }
                }
                positionsToSave.add(position);
            }
        }
        Boolean successfulSave = false;
        try{
            positionDao.save(positionsToSave);
            successfulSave = true;
            logger.info(positionsToSave.size() + " Position Updates saved successfully");
        }catch(Exception exception){
            logger.error("Failed to persist latest position updates to database");
            logger.error(exception);
        }

        if(successfulSave){
            removeSavedPositions(mostRecentUpdateTime);
            PositionPersistEndedNotification ended = new PositionPersistEndedNotification(DateTime.now(DateTimeZone.UTC), mostRecentUpdateTime);
            internalEventPublisher.publishPositionPersistEndedNotification(ended);
        }
    }
}

Spring上下文是否在运行时加载成功?我发现在xsd(3.0和3.2)中共存的不同版本的名称空间定义中存在一些不一致之处。您可以尝试在这些名称空间中保持一致的相同版本,然后再试一次吗?

应用程序正在通过监听上下文被加载,然后在ContextRefreshedEvent上执行一个方法来启动。

当我从应用程序中删除这个ApplicationEventListener并简单地调用bean上的公共方法来启动服务(而不是依赖于ApplicationEventListener)时,应用程序随后正常启动,所有@Scheduled注释都按预期工作。

最新更新