解決quartz的Job類中使用註解Service為null的辦法
專案中需要繼承Quartz框架。專案的環境是SSM框架,spring4.3,Quartz1.6版本,Intellij IDEA 2017.1
遇到的問題是:在quartz的Job中使用@Autowired自動注入service時候報錯,報service為null。
原先程式碼如下:
public class XXXJob implements Job{
@AutoWired
XXXService xxxService;
@Override
public void execute(JobExecutionContext jobContext) throws JobExecutionException{
System.out.println(xxxService.getResult());
}
}
原來在非spring容器裡面呼叫service的方法需要使用工具類獲取service,ApplicationContext.getBean(“xxxService”)
然後寫了工具類之後,又報出no bean named ‘xxxService’ available,沒脾氣,還是獲取不到這個service,再去網上搜索Quartz的Job類中如何使用service,搜了一大堆相同的方法,比如什麼配置AdaptableJobFactory,試了都沒有用,還是報錯。最後根據下面兩個部落格的內容整合之後,可以使用service了。
如何在Java Filter 中注入 Service
ServletContextListener使用
最後程式碼如下:
QuartzServletContextListener 程式碼如下:
public class QuartzServletContextListener extends QuartzInitializerListener {
public static final String MY_CONTEXT_NAME = "servletContext";
@Override
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
super.contextDestroyed(sce);
}
@Override
public void contextInitialized(ServletContextEvent sce) {
// TODO Auto-generated method stub
super.contextInitialized(sce);
ServletContext servletContext = sce.getServletContext();
StdSchedulerFactory factory = (StdSchedulerFactory) servletContext
.getAttribute(QuartzInitializerListener.QUARTZ_FACTORY_KEY);
try {
factory.getScheduler().getContext()
.put(QuartzServletContextListener.MY_CONTEXT_NAME, servletContext);
} catch (SchedulerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
將QuartzServletContextListener 配置到web.xml中去
<listener>
<listener-class>x.x.x.QuartzServletContextListener</listener-class>
</listener>
XXXJob的程式碼如下:
public class XXXJob implements Job{
@Override
public void execute(JobExecutionContext jobContext) throws JobExecutionException{
try {
ServletContext context = null;
try {
context = (ServletContext) jobContext.getScheduler().getContext()
.get(QuartzServletContextListener.MY_CONTEXT_NAME);
} catch (SchedulerException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
XmlWebApplicationContext cxt = (XmlWebApplicationContext)WebApplicationContextUtils.getWebApplicationContext(context);
XXXService xxxService = (XXXService)cxt.getBean("XXXService");
System.out.println(xxxService.getResult());
}
}
以上是一種方法,比較複雜,有一種更簡單的,問題主要根源就是如何在非spring容器中(非controller中)使用service方法。
編寫工具類繼承ApplicationContextAware類
public class ApplicationContextHelper implements ApplicationContextAware{
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context=applicationContext;
}
public static Object getBean(String beanName){return context.getBean(beanName);}
public static <T> T getBean(Class<T> tClass){return context.getBean(tClass);}
}
隨後在spring-mvc.xml中配置bean如下:
<bean id="SpringApplicationContext" class="com.cjs.example.utils.ApplicationContextHelper"></bean>
使用時候,如下:
xxxService service=ApplicationContextHelper.getBean(xxxService.class);