Quartz实现的job接口无法注入实例bean

本文探讨了在Spring框架中使用Quartz进行任务调度时遇到的Bean注入问题。主要原因是通过反射创建Job实例而非Spring容器管理导致。文章提供了解决方案,即利用SpringContextUtil工具类在初始化阶段完成必要的Bean注入。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

做项目的时候遇见一个问题,其实以前也遇到过类似的,虽然最后用new ClassPathXmlApplicationContext的方式解决了,但是也是治标不治本。

今天再次遇见,总结一下原因和目前觉得比较好的解决方法吧!

情形:

首先我通过Spring中Quartz的Factory工厂来创建Job,这个job其实是一个调度管理器,动态读取数据库的信息,然后再创建和管理更多的job。

    <bean id="SpringQtzJobMethod"
        class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject">
            <ref bean="SpringQtzJob" />
        </property>
        <property name="targetMethod">
        	<!-- 需要执行的方法名称  -->
            <value>init</value>
        </property>
    </bean>
当我再用java创建job的以后,发现我实现job接口的类中所有的bean都没办法注入了。

原因:

我通过反射的方式创建job类(代码中实现),而不是用Spring来创建(不是Spring容器中的实例),所以获取不到bean。

其实还有一种配置方式,也是反射的方式创建:

<bean name="initJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
     <property name="jobClass" value="com.xxx.services.InitJob" />
</bean>

解决方案:

 job的实现每次都会创建一个任务实例,如果在job中去做new ClassPathXmlApplicationContext("classpath*:xxx");的话可以解决上面的情况,但是job每次都会创建一个实例,这样在高并发或者长时间使用下,很容易就会内存溢出;

因此,比较好的解决办法是在spring配置文件中加入ApplicationContextAware 的实现类SpringContextUtil ,让spring在初始化的时候做一次需要使用的service或dao的bean初始化,这样在job中就可以通过这个util去拿到已经初始化的实例,而不用每次都创建一次context。

package com.framework.util;

import java.util.Locale;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * 系统bean帮助类
 */
public class SpringContextUtil implements ApplicationContextAware  {

	private static ApplicationContext context;

	@Override
	@SuppressWarnings("static-access" )
	public void setApplicationContext(ApplicationContext contex)
			throws BeansException {
		// TODO Auto-generated method stub
		 this.context = contex;
	}
	public static Object getBean(String beanName){
		return context.getBean(beanName);
	}
	
	public static String getMessage(String key){
		return context.getMessage(key, null, Locale.getDefault());
	}
}
在spring的配置中加上这个util

<bean id="SpringContextUtil" class="com.framework.util.SpringContextUtil"></bean>
调用的时候这样做

TfUserChargeService tfUserChargeService = (TfUserChargeService)SpringContextUtil.getBean("tfUserChargeService");
List<TfProductMonthCharge> chargeList= tfUserChargeService.countProductMonthCharge(lastMonth);
......

之前也写过一篇spring中bean的获取方式总结,连接http://blog.youkuaiyun.com/a714832876/article/details/47661003


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值