1. 程式人生 > >解決quartz的Job類中使用註解Service為null的辦法

解決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);