我正在运行 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);
}
}
}
任何帮助,将不胜感激。