美文网首页
Quartz Job中注入bean最简单的方法

Quartz Job中注入bean最简单的方法

作者: _Kantin | 来源:发表于2021-07-10 17:02 被阅读0次

背景

  • 最近在做一个大数据的项目,需要在项目中加点定时任务。按照之前的经验已经用过很多次的Quartz无疑是最佳的选择。
  • 由于之前的项目用Quartz并没有持久化,所有Job中的bean是直接通过jobDataMap进行传递。但本次需要持久化,bean是无法通过Quartz持久化到DB,会报错。
  • 而在 Quartz 的 Job 中 @Autowired 一个 Spring Bean 的时候会报空指针异常。

原因

  • 出现这个问题是因为定时任务的 Job 对象实例化的过程是通过 Quartz 内部自己完成的,但是我们通过 Spring 进行注入的 Bean 却是由 Spring 容器管理的,Quartz 内部无法感知到 Spring 容器管理的 Bean,所以没有办法在创建 Job 的时候就给装配进去。
  • 经过对源码的分析,发现比较复杂,需要自己定义一个JobFactory交给spring管理,同时还得将自定义的 JobFactory 设置到 Schedule中,相对来说比较复杂。
  • 上述方案有点复杂(主要是代码比较多)。既然我们依赖的bean是已经由spring管理的,那么我们取出来用不就好?也即是通过getBean方法直接取值。这种方法可以实现目的,同时分析了下好像也没有啥特别大的弊端 (若有求指点)

代码

  • 工具类
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.stereotype.Component;

/**
 * Created by linzikang
 */
@Component
public class SpringUtil implements ApplicationContextAware {

    private static final Logger LOGGER = LoggerFactory.getLogger(SpringUtil.class);

    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        SpringUtil.context = context;
    }

    /**
     * 获取 Spring Bean
     * @param clazz 类
     * @param <T>   泛型
     * @return 对象
     */
    public static <T> T getBean(Class<T> clazz) {
        if (clazz == null) {
            return null;
        }
        return context.getBean(clazz);
    }

    /**
     * 获取 Spring Bean
     * @param bean 名称
     * @param <T>  泛型
     * @return 对象
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String bean) {
        if (bean == null) {
            return null;
        }
        return (T) context.getBean(bean);
    }

    /**
     * 获取 Spring Bean
     * @param beanName 名称
     * @param clazz    类
     * @param <T>      泛型
     * @return 对象
     */
    public static <T> T getBean(String beanName, Class<T> clazz) {
        if (null == beanName || "".equals(beanName.trim())) {
            return null;
        }
        if (clazz == null) {
            return null;
        }
        return (T) context.getBean(beanName, clazz);
    }

    /**
     * 获取上下文
     * @return 上下文
     */
    public static ApplicationContext getContext() {
        if (context == null) {
            throw new RuntimeException("There has no Spring ApplicationContext!");
        }
        return context;
    }

    /**
     * 发布事件
     * @param event 事件
     */
    public static void publishEvent(ApplicationEvent event) {
        if (context == null) {
            return;
        }
        try {
            context.publishEvent(event);
        } catch (Exception ex) {
            LOGGER.error(ex.getMessage());
        }
    }
}
  • bean获取:直接调用SpringUtil.getBean(xxx.class)即可,只有你的bean已经被spring托管过的,那么在任何地方都可以调用到。

相关文章

网友评论

      本文标题:Quartz Job中注入bean最简单的方法

      本文链接:https://www.haomeiwen.com/subject/rkwcpltx.html