为什么 spring bean 不能注入到 quartz 作业中?
Why spring bean can't be injected in quartz job?
我现在正在编写一个 quartz 作业,每天 3:00 上午开始将数据保存在数据库和 redis 中。但是现在遇到一个问题,试了很多次都解决不了
工作:
public class QuartzScheduler implements ServletContextListener {
private static Logger logger = Logger.getLogger(QuartzScheduler.class);
@Autowired
private ExchangeRateConfigBean exchangeRateConfigBean;
private Scheduler scheduler = null;
@Override
public void contextInitialized(ServletContextEvent servletContext) {
try {
ExchangeRateConfig exchangeRateConfig = exchangeRateConfigBean.setUpConfigurationFromConfigFile();
if(!exchangeRateConfig.getJob_fire()) {
logger.info("ExchangeRate Job Info: Current Exchange Rate Job flag is not open. Wont start the job!");
return;
}
} catch (Exception e) {
logger.error("ExchangeRate Job Info: Something wrong when analyzing config.properties file!");
logger.error(e.getMessage());
logger.error(e.getStackTrace());
logger.error(e.getCause());
return;
}
try {
scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
logger.info("ExchangeRate Job Info: Exchange Rate job starting......");
} catch (SchedulerException ex) {
logger.error(ex);
}
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
try {
scheduler.shutdown();
} catch (SchedulerException e) {
logger.error(e);
}
}
在这项工作中,我自动装配了组件 ExchangeRateConfigBean,但是当我调试时,我看到该实例为空。
下面的 spring 配置:
<bean id="exchangeRateConfigBean" class="com.letv.exchangerate.bean.impl.ExchangeRateConfigBeanImpl">
<constructor-arg ref="exchangeRateErrorBean" />
</bean>
<bean id="exchangeRateErrorBean" class="com.letv.exchangerate.bean.impl.ExchangeRateErrorBeanImpl">
</bean>
下面的配置Bean:
public class ExchangeRateConfigBeanImpl implements ExchangeRateConfigBean {
public ExchangeRateConfigBeanImpl(){}
public ExchangeRateConfigBeanImpl(ExchangeRateErrorBean exchangeRateErrorBean)
{
this.exchangeRateErrorBean = exchangeRateErrorBean;
}
private static Logger logger = Logger.getLogger(ExchangeRateConfigBeanImpl.class.getClass());
private ExchangeRateErrorBean exchangeRateErrorBean;
@Override
public ExchangeRateConfig setUpConfigurationFromConfigFile() throws IOException {
InputStream inputStream = null;
ExchangeRateConfig exchangeRateConfig = null;
try {
Properties prop = new Properties();
String propFileName = "config.properties";
inputStream = getClass().getClassLoader().getResourceAsStream(propFileName);
exchangeRateConfig = new ExchangeRateConfig();
if (inputStream != null) {
prop.load(inputStream);
} else {
logger.error("property file '" + propFileName + "' not found in the classpath");
throw new FileNotFoundException("property file '" + propFileName + "' not found in the classpath");
}
String job_fire_tmp = prop.getProperty("job_fire");
exchangeRateConfig.setJob_fire(job_fire_tmp.isEmpty() ? false : Boolean.parseBoolean(job_fire_tmp));
return exchangeRateConfig;
} catch (IOException e) {
logger.error(e.getStackTrace());
return exchangeRateConfig;
} finally {
inputStream.close();
}
}
在config bean中,我使用了constructor injection来注入上面的error bean。错误 bean 的代码列表如下:
public class ExchangeRateErrorBeanImpl implements ExchangeRateErrorBean{
public ExchangeRateErrorBeanImpl(){}
@Override
public ExchangeRateError getExchangeRateError(String content) {
if (content.isEmpty())
return null;
if (!content.contains(":"))
return null;
String[] strArray = content.split(":");
return new ExchangeRateError(strArray[0], strArray[1]);
}
}
有人可以帮忙吗?为什么我在作业 class 中自动装配 Config bean,它会创建空实例?谢谢
在我post这个之前,我已经详细阅读了这个,Why is my Spring @Autowired field null?
但这并没有节省我的时间。
您的代码将 QuartzScheduler 显示为 ServletContextListener 的一个实例。这只会创建一个 Java bean。您的 Quartz Scheduler class 必须是 Spring applicationContext 中的一个 bean。只有这样其他依赖项才会被自动装配。例如参考这个 - http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html#scheduling-quartz
我现在正在编写一个 quartz 作业,每天 3:00 上午开始将数据保存在数据库和 redis 中。但是现在遇到一个问题,试了很多次都解决不了
工作:
public class QuartzScheduler implements ServletContextListener {
private static Logger logger = Logger.getLogger(QuartzScheduler.class);
@Autowired
private ExchangeRateConfigBean exchangeRateConfigBean;
private Scheduler scheduler = null;
@Override
public void contextInitialized(ServletContextEvent servletContext) {
try {
ExchangeRateConfig exchangeRateConfig = exchangeRateConfigBean.setUpConfigurationFromConfigFile();
if(!exchangeRateConfig.getJob_fire()) {
logger.info("ExchangeRate Job Info: Current Exchange Rate Job flag is not open. Wont start the job!");
return;
}
} catch (Exception e) {
logger.error("ExchangeRate Job Info: Something wrong when analyzing config.properties file!");
logger.error(e.getMessage());
logger.error(e.getStackTrace());
logger.error(e.getCause());
return;
}
try {
scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
logger.info("ExchangeRate Job Info: Exchange Rate job starting......");
} catch (SchedulerException ex) {
logger.error(ex);
}
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
try {
scheduler.shutdown();
} catch (SchedulerException e) {
logger.error(e);
}
}
在这项工作中,我自动装配了组件 ExchangeRateConfigBean,但是当我调试时,我看到该实例为空。
下面的 spring 配置:
<bean id="exchangeRateConfigBean" class="com.letv.exchangerate.bean.impl.ExchangeRateConfigBeanImpl">
<constructor-arg ref="exchangeRateErrorBean" />
</bean>
<bean id="exchangeRateErrorBean" class="com.letv.exchangerate.bean.impl.ExchangeRateErrorBeanImpl">
</bean>
下面的配置Bean:
public class ExchangeRateConfigBeanImpl implements ExchangeRateConfigBean {
public ExchangeRateConfigBeanImpl(){}
public ExchangeRateConfigBeanImpl(ExchangeRateErrorBean exchangeRateErrorBean)
{
this.exchangeRateErrorBean = exchangeRateErrorBean;
}
private static Logger logger = Logger.getLogger(ExchangeRateConfigBeanImpl.class.getClass());
private ExchangeRateErrorBean exchangeRateErrorBean;
@Override
public ExchangeRateConfig setUpConfigurationFromConfigFile() throws IOException {
InputStream inputStream = null;
ExchangeRateConfig exchangeRateConfig = null;
try {
Properties prop = new Properties();
String propFileName = "config.properties";
inputStream = getClass().getClassLoader().getResourceAsStream(propFileName);
exchangeRateConfig = new ExchangeRateConfig();
if (inputStream != null) {
prop.load(inputStream);
} else {
logger.error("property file '" + propFileName + "' not found in the classpath");
throw new FileNotFoundException("property file '" + propFileName + "' not found in the classpath");
}
String job_fire_tmp = prop.getProperty("job_fire");
exchangeRateConfig.setJob_fire(job_fire_tmp.isEmpty() ? false : Boolean.parseBoolean(job_fire_tmp));
return exchangeRateConfig;
} catch (IOException e) {
logger.error(e.getStackTrace());
return exchangeRateConfig;
} finally {
inputStream.close();
}
}
在config bean中,我使用了constructor injection来注入上面的error bean。错误 bean 的代码列表如下:
public class ExchangeRateErrorBeanImpl implements ExchangeRateErrorBean{
public ExchangeRateErrorBeanImpl(){}
@Override
public ExchangeRateError getExchangeRateError(String content) {
if (content.isEmpty())
return null;
if (!content.contains(":"))
return null;
String[] strArray = content.split(":");
return new ExchangeRateError(strArray[0], strArray[1]);
}
}
有人可以帮忙吗?为什么我在作业 class 中自动装配 Config bean,它会创建空实例?谢谢
在我post这个之前,我已经详细阅读了这个,Why is my Spring @Autowired field null? 但这并没有节省我的时间。
您的代码将 QuartzScheduler 显示为 ServletContextListener 的一个实例。这只会创建一个 Java bean。您的 Quartz Scheduler class 必须是 Spring applicationContext 中的一个 bean。只有这样其他依赖项才会被自动装配。例如参考这个 - http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html#scheduling-quartz