0

我正在运行 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 Application Context 中直接声明 Scheduled 方法可以正常工作 - 但是我非常热衷于使用注释。

这是带注释的类:

**
 * 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);
        }

    }
}

任何帮助,将不胜感激。

4

2 回答 2

2

Spring 上下文是否在运行时成功加载?我看到您在命名空间定义中存在一些不一致之处,其中各种版本在 xsd(3.0 和 3.2)中共存。您可以尝试在这些命名空间中始终使用相同的版本并再试一次吗?

于 2013-05-28T16:57:37.157 回答
0

通过侦听要加载的上下文然后在ContextRefreshedEvent上执行方法来启动应用程序。

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

于 2013-05-28T17:26:46.143 回答