2012-05-03 3 views
2

아주 기본적인 시나리오에서 몇 가지 문제가 있습니다. 자바 웹 앱 (스프링 3)이 있으며 스택에 객체를 저장하고 싶습니다. 그런 다음 스케줄러를 사용하여 스택의 객체를 관리하려고하므로 쿼츠 작업을 구현했습니다. 평범하고 단순합니다. 첫 번째 서비스 클래스에 스택을 삽입하고 작업 클래스에 @Autowired 주석을 삽입한다. 서비스 클래스의 경우 테이블이 성공적으로 주입되지만 작업 클래스의 경우 테이블은 널입니다.두 스레드간에 공유되는 빈에 적용하면 @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

Autowiring은 스프링 빈 공장에서 콩을 만든 경우에만 작동합니다. 빈 팩토리를 사용하지 않고 객체를 생성 했습니까? 즉, new QuartzJSearchJob() 구문을 사용하여 객체를 생성 했습니까?

+0

@Component annotation으로 생성하려고 시도했습니다 – MaVVamaldo

+0

빈 구성을 게시 할 수 있습니까? Bean이 bean factory에 의해 작성되지 않으면 @Component를 추가해도 도움이되지 않습니다. – gigadot

+0

네, 그냥 완료 :-) – MaVVamaldo

-2

나는 당신이 그 때 작동합니다, 당신은이 맵에 개체를 넣어 scheduleFactoryBean, setSchedulerContextAsMap()에 값을 할당해야합니다 생각합니다.

@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

나는 같은 문제, 내 Job.execute(JobExecutionContext context) 방법의 첫 번째 줄 SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);을 추가하여이 문제를 해결했다.

관련 문제