2

我在一个非常基本的场景中遇到了一些麻烦:我有一个 java web 应用程序(spring 3),我想将一些对象存储到堆栈中。然后我想用调度程序管理堆栈中的对象,所以我实现了一个石英作业。干净利落。我将堆栈注入到第一个服务类和带有@Autowired 注释的作业类中。对于服务类,该表已成功注入,但对于作业类,该表为空。这是代码:

要分享的课程

package it.unifi.det.telemat.vr.data;
@Component
public class IndexedNodesStack extends HashMap<IndexedObject, Boolean>{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Override
    public synchronized int size() {
        // TODO Auto-generated method stub
        return super.size();
    }

    //all the HashMap methods are implemented in a synchronized wrapper method

}

第一堂课(@Autowired 成功)

package it.unifi.det.telemat.vr.service;
@Service
public class InnerNodeManager extends ConcreteNodeManager{

    @Autowired
    private IndexedNodesStack indexedNodesStack; //<--- it is actually autowired!


    private void manageIndexedNodes(Boolean isPut, String lri, String features)
    {
        IndexedObject indexedObject = new IndexedObject();
        indexedObject.setId(lri);
        if(features != null && isPut)
            indexedObject.generateFeatures(features);

        indexedNodesStack.put(indexedObject, isPut);
    }

}

作业类(@Autowired 失败)

package it.unifi.det.telemat.vr.service.scheduler;
@Component
public class QuartzJSearchJob extends QuartzJobBean{

    @Autowired
    private IndexedNodesStack indexedNodesStack; //<--- this variable is null :-(

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException
    {
        //do work       
    }
}

编辑:这是 servlet.xml

<context:component-scan base-package="it.unifi.det.telemat.vr" />

<bean name="searchJob"
class="org.springframework.scheduling.quartz.JobDetailBean">
    <property name="jobClass" value="it.unifi.det.telemat.vr.service.scheduler.QuartzJSearchJob" />
</bean>

<bean id="searchJobTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
    <property name="jobDetail" ref="searchJob" />
    <property name="cronExpression" value="0/50 * * * * ?" />
</bean>

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
    <list>
        <ref bean="searchJobTrigger" />
        </list>
    </property>
</bean>

也许我对线程之间的资源共享缺乏一些了解,因为这是我在这个领域的第一次尝试。我错过了什么?

4

6 回答 6

2

仅当 bean 是从 Spring bean 工厂创建时,自动装配才有效。您是否在不使用 bean 工厂的情况下创建对象,即使用new QuartzJSearchJob()语法创建它?

于 2012-05-03T17:12:09.527 回答
2

好的,我终于明白了。它不起作用,因为spring没有实例化quartzJSearchJob,quartz可以。要在作业中注入的 bean 必须通过SchedulerFacoryBean. 这是使事情正常进行的配置。

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref bean="searchJobTrigger" />
        </list>
    </property>
    <property name="schedulerContextAsMap">
    <map>
       <entry key="indexedNodesStack" value-ref="indexedNodesStack" />
    </map>
    </property>
</bean>
于 2012-05-04T09:40:25.540 回答
0

QuartzJSearchJob不被识别为 bean,因为它没有类级别的注释。尝试@Component

于 2012-05-03T17:11:13.830 回答
0

您忘记了“jobDetails”属性:

<property name="jobDetails">
    <list>
        <ref bean="searchJob" />
    </list>
</property>

您还需要使用org.springframework.scheduling.quartz.JobDetailFactoryBean而不是org.springframework.scheduling.quartz.JobDetailBean.

像这样插入它:

<bean name="searchJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
    <property name="jobClass" value="it.unifi.det.telemat.vr.service.scheduler.QuartzJSearchJob" />
</bean>

<bean id="searchJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
    <property name="jobDetail" ref="searchJob" />
    <property name="cronExpression" value="0/50 * * * * ?" />
</bean>

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref bean="searchJobTrigger" />
        </list>
    </property>
    <property name="jobDetails">
        <list>
            <ref bean="searchJob" />
        </list>
    </property>
</bean>
于 2015-01-09T15:43:24.810 回答
0

我有同样的问题,我通过添加SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);作为我的Job.execute(JobExecutionContext context)方法的第一行来解决这个问题。

于 2016-11-24T15:28:00.620 回答
-2

我认为你必须在 , 中分配一个值scheduleFactoryBeansetSchedulerContextAsMap()你把你的对象放在这个地图中,然后它就会起作用。

@Bean(name = "scheduler")
  public SchedulerFactoryBean schedulerFactory()
  {
    SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
    schedulerFactory.setDataSource(dataSource);
    schedulerFactory.setAutoStartup(true);
    schedulerFactory.setGlobalJobListeners(globalJobListeners);
    schedulerFactory.setSchedulerContextAsMap(contextMap());
    schedulerFactory.setQuartzProperties(schedulerProperties());
    return schedulerFactory;
  }
于 2014-12-18T09:37:47.113 回答