2012-05-03 34 views
2

我對一個非常基本的場景有一些麻煩:我有一個java web應用程序(spring 3),我想將一些對象存儲到堆棧中。然後我想用一個調度器來管理堆棧中的對象,所以我實現了一個石英工作。乾淨利落。我使用@Autowired註解在第一個服務類和作業類中注入堆棧。對於服務類,表已成功注入,但對於作業類,表爲空。 下面的代碼:如果應用於兩個線程之間共享的bean,@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> 

也許我缺乏一些線程間資源共享的知識,因爲這是我在這個領域的第一次嘗試。 我錯過了什麼?

+0

你需要展示你如何創建對象來解釋爲什麼它不會在春天被正確初始化。它是如何初始化的? – ianpojman

+0

這個工作是通過@Component註釋創建的(我編輯了我的問題來糾正它) – MaVVamaldo

回答

2

好的,最後我明白了。 它不起作用,因爲春天沒有實例化quartzJSearchJob,石英。在工作中注入的豆必須通過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> 
0

QuartzJSearchJob不被識別爲一個bean,因爲它沒有類級註釋。嘗試@Component

+0

我的錯,我在代碼中實際存在的時候省略了粘貼操作中的@Component。我編輯了我的問題。 – MaVVamaldo

2

自動裝配只有在bean是從Spring bean工廠創建時纔有效。你是否在不使用bean factory的情況下創建對象,即使用new QuartzJSearchJob()語法創建它?

+0

我嘗試使用@Component註釋創建它 – MaVVamaldo

+0

您可以發佈您的bean配置嗎?如果bean不是由bean工廠創建的,則添加@Component不會有幫助。 – gigadot

+0

是的,剛剛完成:-) – MaVVamaldo

-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; 
    } 
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> 
0

我有同樣的問題,我加入SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);作爲我Job.execute(JobExecutionContext context)方法的第一線解決了這個。

相關問題