- 浏览: 979839 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
Spring与Quartz集成详解:http://donald-draper.iteye.com/blog/2323591
Spring与Quarzt整合时,job的定义有两种方式,分别为JobDetailFactoryBean与MethodInvokingJobDetailFactoryBean,这两种方法有什么不同呢,我们通过源码来看一下:
第一种:
//bean包装实现类
//AbstractPropertyAccessor
第二种:
//方法包装类
最后再来看一下触发器任务工厂类
//触发器任务工厂类
//CronTrigger实现类
总结:
JobDetailFactoryBean是通过jobDetails属性来生产job;
MethodInvokingJobDetailFactoryBean内置静态类MethodInvokingJob,
而MethodInvokingJob继承了QuartzJobBean,同时与一个内部变量MethodInvoker;
在MethodInvokingJobDetailFactoryBean属性初始化完后,通过MethodInvoker封装TargetObject的TargetMethod方法并在executeInternal中调用MethodInvoker.invoke()来生产job。
Spring与Quarzt整合时,job的定义有两种方式,分别为JobDetailFactoryBean与MethodInvokingJobDetailFactoryBean,这两种方法有什么不同呢,我们通过源码来看一下:
第一种:
public class JobDetailFactoryBean implements FactoryBean, BeanNameAware, ApplicationContextAware, InitializingBean { public JobDetailFactoryBean() { jobDataMap = new JobDataMap(); durability = false; requestsRecovery = false; } public void setName(String name) { this.name = name; } public void setGroup(String group) { this.group = group; } public void setDescription(String description) { this.description = description; } //设置beanName public void setBeanName(String beanName) { this.beanName = beanName; } //设置applicationContext public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } //设置applicationContextJobDataKey public void setApplicationContextJobDataKey(String applicationContextJobDataKey) { this.applicationContextJobDataKey = applicationContextJobDataKey; } public void afterPropertiesSet() { //设置默认的job,name和group if(name == null) name = beanName; if(group == null) group = "DEFAULT"; if(applicationContextJobDataKey != null) { if(applicationContext == null) throw new IllegalStateException("JobDetailBean needs to be set up in an ApplicationContext to be able to handle an 'applicationContextJobDataKey'"); //配置jobDataMap getJobDataMap().put(applicationContextJobDataKey, applicationContext); } Class jobDetailClass; try { jobDetailClass = ClassUtils.forName("org.quartz.impl.JobDetailImpl", getClass().getClassLoader()); } catch(ClassNotFoundException ex) { jobDetailClass = org/quartz/JobDetail; } BeanWrapper bw = new BeanWrapperImpl(jobDetailClass); MutablePropertyValues pvs = new MutablePropertyValues(); pvs.add("name", name); pvs.add("group", group); pvs.add("jobClass", jobClass); pvs.add("jobDataMap", jobDataMap); pvs.add("durability", Boolean.valueOf(durability)); pvs.add("requestsRecovery", Boolean.valueOf(requestsRecovery)); pvs.add("description", description); //设置属性 bw.setPropertyValues(pvs); //或JobDetail实例 jobDetail = (JobDetail)bw.getWrappedInstance(); } //设置属性值 public void setPropertyValue(String propertyName, Object value) throws BeansException { BeanWrapperImpl nestedBw; try { nestedBw = getBeanWrapperForPropertyPath(propertyName); } PropertyTokenHolder tokens = getPropertyNameTokens(getFinalPath(nestedBw, propertyName)); nestedBw.setPropertyValue(tokens, new PropertyValue(propertyName, value)); } //设置job类 public void setJobClass(Class jobClass) { this.jobClass = jobClass; } //返回的是jobDetail public JobDetail getObject() { return jobDetail; } public Class getObjectType() { return org/quartz/JobDetail; } public boolean isSingleton() { return true; } public volatile Object getObject() throws Exception { return getObject(); } private String name; private String group; private Class jobClass; private JobDataMap jobDataMap; private boolean durability;//任务完成之后是否依然保留到数据库,默认false private boolean requestsRecovery; private String description; private String beanName; private ApplicationContext applicationContext; private String applicationContextJobDataKey; private JobDetail jobDetail; }
//bean包装实现类
public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWrapper { public BeanWrapperImpl(Class clazz) { nestedPath = ""; autoGrowNestedPaths = false; autoGrowCollectionLimit = 2147483647; registerDefaultEditors(); //设置bean包装实现类实例 setWrappedInstance(BeanUtils.instantiateClass(clazz)); } public void setWrappedInstance(Object object) { setWrappedInstance(object, "", null); } public void setWrappedInstance(Object object, String nestedPath, Object rootObject) { Assert.notNull(object, "Bean object must not be null"); this.object = object; this.nestedPath = nestedPath == null ? "" : nestedPath; this.rootObject = "".equals(this.nestedPath) ? object : rootObject; nestedBeanWrappers = null; typeConverterDelegate = new TypeConverterDelegate(this, object); setIntrospectionClass(object.getClass()); } protected void setIntrospectionClass(Class clazz) { if(cachedIntrospectionResults != null && !clazz.equals(cachedIntrospectionResults.getBeanClass())) cachedIntrospectionResults = null; } //返回包装类实例 public final Object getWrappedInstance() { return object; } private static final Log logger = LogFactory.getLog(org/springframework/beans/BeanWrapperImpl); private Object object; private String nestedPath; private Object rootObject; private AccessControlContext acc; private CachedIntrospectionResults cachedIntrospectionResults; private Map nestedBeanWrappers; private boolean autoGrowNestedPaths; private int autoGrowCollectionLimit; }
//AbstractPropertyAccessor
public abstract class AbstractPropertyAccessor extends TypeConverterSupport implements ConfigurablePropertyAccessor { //设置bean所有属性 public void setPropertyValues(PropertyValues pvs) throws BeansException { setPropertyValues(pvs, false, false); } //设置bean所有属性 public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid) throws BeansException { List propertyAccessExceptions = null; List propertyValues = (pvs instanceof MutablePropertyValues) ? ((MutablePropertyValues)pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()); Iterator iterator = propertyValues.iterator(); do { if(!iterator.hasNext()) break; PropertyValue pv = (PropertyValue)iterator.next(); try { setPropertyValue(pv); } } while(true) } //设置bean单个属性 public void setPropertyValue(PropertyValue pv) throws BeansException { setPropertyValue(pv.getName(), pv.getValue()); } }
第二种:
public class MethodInvokingJobDetailFactoryBean extends ArgumentConvertingMethodInvoker implements FactoryBean, BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, InitializingBean { public static class StatefulMethodInvokingJob extends MethodInvokingJob implements StatefulJob {} public static class MethodInvokingJob extends QuartzJobBean { public void setMethodInvoker(MethodInvoker methodInvoker) { this.methodInvoker = methodInvoker; } protected void executeInternal(JobExecutionContext context) throws JobExecutionException { try { ReflectionUtils.invokeMethod(MethodInvokingJobDetailFactoryBean.setResultMethod, context, new Object[] { methodInvoker.invoke() }); } } } public MethodInvokingJobDetailFactoryBean() { group = "DEFAULT"; concurrent = true; beanClassLoader = ClassUtils.getDefaultClassLoader(); } public void afterPropertiesSet() throws ClassNotFoundException, NoSuchMethodException { //初始化MethodInvoker prepare(); String name = this.name == null ? beanName : this.name; Class jobClass = concurrent ? org/springframework/scheduling/quartz/MethodInvokingJobDetailFactoryBean$MethodInvokingJob : org/springframework/scheduling/quartz/MethodInvokingJobDetailFactoryBean$StatefulMethodInvokingJob; if(jobDetailImplClass != null) { jobDetail = (JobDetail)BeanUtils.instantiate(jobDetailImplClass); BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(jobDetail); bw.setPropertyValue("name", name); bw.setPropertyValue("group", group); bw.setPropertyValue("jobClass", jobClass); bw.setPropertyValue("durability", Boolean.valueOf(true)); //设置jobDetails的jobDataMap ((JobDataMap)bw.getPropertyValue("jobDataMap")).put("methodInvoker", this); } else { jobDetail = new JobDetail(name, group, jobClass); jobDetail.setVolatility(true); jobDetail.setDurability(true); jobDetail.getJobDataMap().put("methodInvoker", this); } if(jobListenerNames != null) { String as[] = jobListenerNames; int i = as.length; for(int j = 0; j < i; j++) { String jobListenerName = as[j]; if(jobDetailImplClass != null) throw new IllegalStateException("Non-global JobListeners not supported on Quartz 2 - manually register a Matcher against the Quartz ListenerManager instead"); //添加job监听器 jobDetail.addJobListener(jobListenerName); } } postProcessJobDetail(jobDetail); } protected void postProcessJobDetail(JobDetail jobdetail) { } //获取目标类型 public Class getTargetClass() { Class targetClass = super.getTargetClass(); if(targetClass == null && targetBeanName != null) { Assert.state(beanFactory != null, "BeanFactory must be set when using 'targetBeanName'"); targetClass = beanFactory.getType(targetBeanName); } return targetClass; } //获取目标实例 public Object getTargetObject() { Object targetObject = super.getTargetObject(); if(targetObject == null && targetBeanName != null) { Assert.state(beanFactory != null, "BeanFactory must be set when using 'targetBeanName'"); targetObject = beanFactory.getBean(targetBeanName); } return targetObject; } //返回jobDetail public JobDetail getObject() { return jobDetail; } public Class getObjectType() { return jobDetail == null ? org/quartz/JobDetail : jobDetail.getClass(); } public boolean isSingleton() { return true; } public volatile Object getObject() throws Exception { return getObject(); } private static Class jobDetailImplClass; private static Method setResultMethod; private String name; private String group; private boolean concurrent; private String targetBeanName; private String jobListenerNames[]; private String beanName; private ClassLoader beanClassLoader; private BeanFactory beanFactory; private JobDetail jobDetail; static { try { jobDetailImplClass = ClassUtils.forName("org.quartz.impl.JobDetailImpl", org/springframework/scheduling/quartz/MethodInvokingJobDetailFactoryBean.getClassLoader()); } try { Class jobExecutionContextClass = ClassUtils.forName("org.quartz.JobExecutionContext", org/springframework/scheduling/quartz/MethodInvokingJobDetailFactoryBean.getClassLoader()); setResultMethod = jobExecutionContextClass.getMethod("setResult", new Class[] { java/lang/Object }); } } }
//方法包装类
public class MethodInvoker { public void prepare() throws ClassNotFoundException, NoSuchMethodException { if(staticMethod != null) { int lastDotIndex = staticMethod.lastIndexOf('.'); if(lastDotIndex == -1 || lastDotIndex == staticMethod.length()) throw new IllegalArgumentException("staticMethod must be a fully qualified class plus method name: e.g. 'example.MyExampleClass.myExampleMethod'"); String className = staticMethod.substring(0, lastDotIndex); String methodName = staticMethod.substring(lastDotIndex + 1); this.targetClass = resolveClassName(className); this.targetMethod = methodName; } Class targetClass = getTargetClass(); String targetMethod = getTargetMethod(); if(targetClass == null) throw new IllegalArgumentException("Either 'targetClass' or 'targetObject' is required"); if(targetMethod == null) throw new IllegalArgumentException("Property 'targetMethod' is required"); Object arguments[] = getArguments(); Class argTypes[] = new Class[arguments.length]; for(int i = 0; i < arguments.length; i++) argTypes[i] = arguments[i] == null ? java/lang/Object : arguments[i].getClass(); try { //获取targetClass的targetMethod方法,参数为argTypes methodObject = targetClass.getMethod(targetMethod, argTypes); } catch(NoSuchMethodException ex) { methodObject = findMatchingMethod(); if(methodObject == null) throw ex; } } //反射调用方法 public Object invoke() throws InvocationTargetException, IllegalAccessException { Object targetObject = getTargetObject(); Method preparedMethod = getPreparedMethod(); if(targetObject == null && !Modifier.isStatic(preparedMethod.getModifiers())) { throw new IllegalArgumentException("Target method must not be non-static without a target"); } else { ReflectionUtils.makeAccessible(preparedMethod); //执行目标targetObject的目标方法targetMethod,参数为arguments[] return preparedMethod.invoke(targetObject, getArguments()); } } //jobDetails类的方法 public Method getPreparedMethod() throws IllegalStateException { if(methodObject == null) throw new IllegalStateException("prepare() must be called prior to invoke() on MethodInvoker"); else return methodObject; } public Object getTargetObject() { return targetObject; } public String getTargetMethod() { return targetMethod; } private Class targetClass;//目标类 private Object targetObject;//目标实体 private String targetMethod;//目标方法 private String staticMethod; private Object arguments[]; private Method methodObject; }
最后再来看一下触发器任务工厂类
//触发器任务工厂类
public class CronTriggerFactoryBean implements FactoryBean, BeanNameAware, InitializingBean { public CronTriggerFactoryBean() { jobDataMap = new JobDataMap(); startDelay = 0L; } public void afterPropertiesSet() { if(name == null) name = beanName; if(group == null) group = "DEFAULT"; if(jobDetail != null) jobDataMap.put("jobDetail", jobDetail); if(startDelay > 0L || startTime == null) startTime = new Date(System.currentTimeMillis() + startDelay); if(timeZone == null) timeZone = TimeZone.getDefault(); Class cronTriggerClass; Method jobKeyMethod; try { cronTriggerClass = ClassUtils.forName("org.quartz.impl.triggers.CronTriggerImpl", getClass().getClassLoader()); jobKeyMethod = org/quartz/JobDetail.getMethod("getKey", new Class[0]); } //新建cronTriggerClass的包装类 BeanWrapper bw = new BeanWrapperImpl(cronTriggerClass); MutablePropertyValues pvs = new MutablePropertyValues(); pvs.add("name", name); pvs.add("group", group); if(jobKeyMethod != null) { pvs.add("jobKey", ReflectionUtils.invokeMethod(jobKeyMethod, jobDetail)); } else { pvs.add("jobName", jobDetail.getName()); pvs.add("jobGroup", jobDetail.getGroup()); } pvs.add("jobDataMap", jobDataMap); pvs.add("startTime", startTime); pvs.add("cronExpression", cronExpression); pvs.add("timeZone", timeZone); pvs.add("calendarName", calendarName); pvs.add("priority", Integer.valueOf(priority)); pvs.add("misfireInstruction", Integer.valueOf(misfireInstruction)); pvs.add("description", description); //设置CronTrigger属性 bw.setPropertyValues(pvs); //获取CronTrigger实例 cronTrigger = (CronTrigger)bw.getWrappedInstance(); } //返回Cron触发器 public CronTrigger getObject() { return cronTrigger; } public Class getObjectType() { return org/quartz/CronTrigger; } public boolean isSingleton() { return true; } public volatile Object getObject() throws Exception { return getObject(); } private static final Constants constants = new Constants(org/quartz/CronTrigger); private String name; private String group; private JobDetail jobDetail;//job private JobDataMap jobDataMap; private Date startTime; private long startDelay; private String cronExpression; private TimeZone timeZone; private String calendarName; private int priority; private int misfireInstruction; private String description; private String beanName; private CronTrigger cronTrigger; }
//CronTrigger实现类
public class CronTriggerImpl extends AbstractTrigger implements CronTrigger, CoreTrigger { private static final long serialVersionUID = -8644953146451592766L; protected static final int YEAR_TO_GIVEUP_SCHEDULING_AT; private CronExpression cronEx; private Date startTime; private Date endTime; private Date nextFireTime; private Date previousFireTime; private transient TimeZone timeZone; static { YEAR_TO_GIVEUP_SCHEDULING_AT = CronExpression.MAX_YEAR; } }
总结:
JobDetailFactoryBean是通过jobDetails属性来生产job;
MethodInvokingJobDetailFactoryBean内置静态类MethodInvokingJob,
而MethodInvokingJob继承了QuartzJobBean,同时与一个内部变量MethodInvoker;
在MethodInvokingJobDetailFactoryBean属性初始化完后,通过MethodInvoker封装TargetObject的TargetMethod方法并在executeInternal中调用MethodInvoker.invoke()来生产job。
发表评论
-
Spring的RequestMappingHandlerMapping详解
2016-09-23 08:40 4591深刻理解IdentityHashMap:http://dona ... -
Spring-RequestMappingHandlerAdapter初始化及请求处理
2016-09-22 11:50 10572看这篇文章之前,最好先看下面这篇,以便更好的理解handler ... -
Spring+Mybatis多数据源的实现
2016-09-21 18:15 3093浅谈Spring事务隔离级别:http://www.cnblo ... -
Spring的DefaultAnnotationHandlerMapping详解
2016-09-20 08:47 5838前面我们讲解过Dispatcher ... -
Spring-DispatcherServlet请求处理
2016-09-19 15:42 1684Spring-DispatcherServlet初始化详解:h ... -
Spring-DispatcherServlet初始化详解
2016-09-19 15:03 3688Spring-DispatcherServlet请求处理:ht ... -
Spring上下文加载监听器ContextLoaderListener--源码解析
2016-09-18 18:10 4655一般在web应用配置Spring上下文如下,那么Context ... -
Spring与Quartz集成-源码分析
2016-09-13 11:50 2711在阅读以下文章之前,如果对Quartz任务调度不是很熟悉,请看 ... -
Spring与Quartz集成详解
2016-09-09 17:52 2816首先这个所有的依赖包就不需要多讲了,首先下载Quazrt发布包 ... -
Spring,ApplicationContextAware的作用
2016-08-24 17:38 7引用:http://blog.csdn.net/kaiwii/ ... -
Spring Interceptor
2016-05-31 17:12 570Spring Interceptor相关知识:http://h ... -
基于注解的Spring AOP
2016-05-31 16:05 921Spring AOP 基本概念:http://hotstron ... -
Spring的Task定时器
2016-05-31 10:34 7051.开启注解,定义扫描包 <mvc:annotation ...
相关推荐
然后,需要配置Job,提供了两种方式来配置Job,分别是MethodInvokingJobDetailFactoryBean和JobDetailFactoryBean。MethodInvokingJobDetailFactoryBean用于调用特定bean的一个方法,而JobDetailFactoryBean更加灵活...
Spring通过`org.springframework.scheduling.quartz`包提供了对Quartz的API封装,包括`SchedulerFactoryBean`、`JobDetailFactoryBean`和`TriggerFactoryBean`等,使得我们可以用声明式的方式定义任务和触发器。...
Spring与Quartz的集成是企业级应用中非常常见的技术组合之一。Quartz是一个功能强大的作业调度框架,而Spring则是Java领域中广泛使用的轻量级控制反转(IoC)容器。两者结合能够提供灵活、高效的任务调度解决方案。 #...
4. **数据库驱动**(可选):根据你使用的数据库类型,可能需要相应的JDBC驱动,例如`mysql-connector-java.jar` - 如果你的任务需要与数据库交互,这将是必不可少的。 通常,有人可能会上传6个jar包,可能是因为...
<bean class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> ``` 在Eclipse中,你可以通过右键点击项目,选择`Run As` -> `Java Application`来启动项目。由于你提到...
标题 "Spring + quartz" 暗示了我们讨论的主题是关于如何在Java应用程序中...结合源码分析和工具使用,可以更深入地理解它们的工作原理和优化策略。在实际项目中,这样的组合能够极大地提升系统的自动化水平和效率。
描述中提到 "quartz-2.2.2-版本+springboot2.x" 暗示了这个压缩包不仅包含 Quartz 框架,还特别强调了与 Spring Boot 2.x 的兼容性。Spring Boot 是一个简化 Spring 应用程序开发的框架,提供了一种快速构建可执行...
Spring框架提供了与Quartz库集成的能力,使得我们可以方便地创建和管理定时任务。 Spring与Quartz的集成主要基于Spring的`TaskExecution`和`TaskScheduling`模块,它允许我们以声明式的方式配置定时任务,同时也...
9. **源码分析**:标签中提到的 "源码" 暗示这个示例可能包含了对这些库的深入理解和使用,或者提供了自定义的扩展。 综上所述,这个示例不仅展示了如何在 Spring 应用中集成和使用 Quartz 定时任务,可能还包括了 ...
此外,Spring还提供了一个`org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean`,可以直接通过指定目标对象和方法来创建`Job`,这样就不需要显式实现`Job`接口。这种方法对于简单的任务来说...
同时,Spring的`MethodInvokingJobDetailFactoryBean`允许你直接调用一个Spring Bean的方法作为定时任务,这进一步提高了灵活性。 总的来说,Spring与Quartz的集成使任务调度变得简单易行。通过Spring的IoC和AOP...
它提供了模型-视图-控制器(MVC)架构,帮助开发者将业务逻辑与表现层分离,提高了代码的组织性和可测试性。而Quartz是Java领域内广泛应用的定时任务库,能够实现定时调度任务,广泛应用于大数据处理、定时报告生成...
Quartz则是一个强大的、开放源码的作业调度框架,它允许开发者精确地安排任务执行时间。Quartz支持复杂的调度策略,如按时间间隔执行、在特定日期执行等。 **整合Spring和Quartz** 1. **引入依赖**:在你的`pom....
Spring框架可以通过`org.springframework.scheduling.quartz`包与Quartz进行集成。下面是一个使用Quartz的例子: ```java import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz....
在本文中,我们将深入探讨Spring Boot中的定时任务,包括如何使用Spring Boot...结合提供的源码资料,你将能更深入地理解和应用这些技术。实践是检验真理的唯一标准,动手尝试编写和调试代码,你的技能将得到显著提升。
通过分析这个项目,你可以深入理解Spring与Quartz的集成方式,以及如何在实际应用中利用它们来实现复杂的定时任务需求。 此外,Quartz还支持JobGroup(任务组)、TriggerGroup(触发器组)、JobDataMap(用于传递...
通过分析源码,开发者可以深入理解其内部工作机制,包括任务调度算法、数据库操作、触发器管理等方面,这对于定制化开发或优化性能非常有帮助。 总结来说,Quartz是一个强大的作业调度框架,它的1.6.4版本提供了...
当需要在Quartz作业中调用由Spring管理的服务时,会出现依赖注入的问题,因为Quartz的工作线程与Spring的ApplicationContext不一致。 为了解决这个问题,我们需要以下步骤: 1. **配置Spring上下文**:首先,在...
Java网上爬虫与定时任务是IT领域中两个重要的技术方向,它们在数据分析、信息收集以及自动化运维等方面有着广泛的应用。本篇文章将详细讲解如何利用Java实现网上爬虫以及结合Quartz实现定时任务。 首先,我们要了解...
Spring与Quartz的集成使得我们可以利用Spring的依赖注入(DI)和AOP特性来更方便地管理定时任务。 首先,我们需要理解Spring定时器的基本概念。Spring Task提供了一个简单的API,允许我们定义和管理定时任务,包括`...