- 浏览: 951846 次
文章分类
- 全部博客 (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 4500深刻理解IdentityHashMap:http://dona ... -
Spring-RequestMappingHandlerAdapter初始化及请求处理
2016-09-22 11:50 10524看这篇文章之前,最好先看下面这篇,以便更好的理解handler ... -
Spring+Mybatis多数据源的实现
2016-09-21 18:15 3042浅谈Spring事务隔离级别:http://www.cnblo ... -
Spring的DefaultAnnotationHandlerMapping详解
2016-09-20 08:47 5790前面我们讲解过Dispatcher ... -
Spring-DispatcherServlet请求处理
2016-09-19 15:42 1644Spring-DispatcherServlet初始化详解:h ... -
Spring-DispatcherServlet初始化详解
2016-09-19 15:03 3636Spring-DispatcherServlet请求处理:ht ... -
Spring上下文加载监听器ContextLoaderListener--源码解析
2016-09-18 18:10 4579一般在web应用配置Spring上下文如下,那么Context ... -
Spring与Quartz集成-源码分析
2016-09-13 11:50 2637在阅读以下文章之前,如果对Quartz任务调度不是很熟悉,请看 ... -
Spring与Quartz集成详解
2016-09-09 17:52 2763首先这个所有的依赖包就不需要多讲了,首先下载Quazrt发布包 ... -
Spring,ApplicationContextAware的作用
2016-08-24 17:38 7引用:http://blog.csdn.net/kaiwii/ ... -
Spring Interceptor
2016-05-31 17:12 530Spring Interceptor相关知识:http://h ... -
基于注解的Spring AOP
2016-05-31 16:05 881Spring AOP 基本概念:http://hotstron ... -
Spring的Task定时器
2016-05-31 10:34 6681.开启注解,定义扫描包 <mvc:annotation ...
相关推荐
class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <!-- trigger触发器 --> class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"> <!-- 3秒...
基于matlab实现二维小波时频图;图像;二维;时频分析;结决问题.rar
pentair 5800 SXT软水机说明书
数据来源:中国电力统计NJ-2021版
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
数据来源:中国劳动统计NJ-2023版
数据来源:中国电力统计NJ-2021版
基于HarmonyOS 4开发的一款新闻类的鸿蒙APP源代码
数据来源:中国人口与就业统计NJ-2023版
重庆大学图书管理系统设计与实现 毕业论文设计(51页).doc
数据来源:中国电力统计NJ-2021版
数据来源:中国电力统计NJ-2021版
PostgreSQL9.6x64-HaoSQL
GEM20U系列曲折缝纫机使用说明书
企业培训管理系统设计与实现.doc
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
数据来源:中国劳动统计NJ-2023版
基于matlab实现的LTE 仿真平台 国外维也纳大学网站 MATLAB仿真.rar
数据来源:中国人口与就业统计NJ-2023版
【Redis开发】lua脚本开发nginx 与 redis 模块 (Lua script development nginx and Redis modules) 文件列表: lua_files (0, 2017-05-21) lua_files\access_control.lua (1813, 2017-05-21) lua_files\app_redis_client.lua (1717, 2017-05-21) lua_files\hello.lua (508, 2017-05-21) lua_files\test.lua (690, 2017-05-21) nginx + lua + redis 过滤请求(连续请求拦截),并可以缓存前置.md (3436, 2017-05-21) nginx docker 镜像.md (1459, 2017-05-21) nginx tcp负载均衡.md (1226, 2017-05-21) nginx 的 Lua 模块安装.md (2931, 2017-05-21) nginx(lua+1.11.2与 1.12.0) docker imag