Liferay 6.1开发学习(十一):调度器-定时任务
在liferay的开发中经常需要执行一些定时调度任务,一般情况下在普通的web开发中我们使用quartz来做调度,但是在Liferay中已经对于调度做了一个封装,方便我们在开发中执行调度任务,liferay中封装了两种方法方便我们做调度扩展。
一、基于Portlet的调度
如某个的调度是在某个portlet中使用的,则可以使用一面的方法:
1、 编写一个类,实现接口:com.liferay.portal.kernel.messageing.MessageListener。如下图所示。其中的doReceive()方法是定时执行的内容。
2、 在liferay-portlet.xml里面注册这个调度类,添加如下代码:
<scheduler-entry> <scheduler-event-listener-class> xxx.cmsnewsgather.NewsGatherMessageListener(上面此类的全路径) </scheduler-event-listener-class> <trigger> <simple> <simple-trigger-value>15</simple-trigger-value> <time-unit>minute</time-unit> </simple> </trigger> </scheduler-entry>
scheduler-event-listener-class:里面的类为第一步里面编写的类
simple-trigger-value:里面为调度周期的数值,time-unit为调度周期的单位。上面的意思为每15分钟执行一次。此时间也可以从配置文件中读取。则将此标签完成<property-key>newsgather.gather.time</property-key>,其中的newsgather.gather.time为属性文件(portal.properties)里面配置的值
Time-unit:表示周期的周期可以为:day、hour、minute、second、week这几个单位。
3、 上面的代码即完成了一个调度器的开始,内容为每15分钟执行一次第一步类里面的doReceive()方法。
二、基于servlet的调度
注:此方法适用于lifery6.0.6,不适用于liferay6.1.x
1、同上,编写一个实现com.liferay.portal.kernel.messageing.MessageListener的类。
2、在相应工程下面的web.xml里面添加servlet的注册信息,如下:
<servlet> <servlet-name>Lucene Servlet</servlet-name> <servlet-class> xx.xx.servlet.xxxServlet </servlet-class> <load-on-startup>2</load-on-startup> </servlet>
3、在上面的servlet的init(ServletConfig servletConfig)方法里面添加如下内容:
super.init(servletConfig); SchedulerEntry schedulerEntry = new SchedulerEntryImpl(); schedulerEntry.setEventListenerClass( xxxMessageListener.class.getName()); schedulerEntry.setTimeUnit(TimeUnit.MINUTE); schedulerEntry.setTriggerType(TriggerType.SIMPLE); schedulerEntry.setTriggerValue(15); try { SchedulerEngineUtil.schedule( schedulerEntry, PortalClassLoaderUtil.getClassLoader()); }
其中的xxxMessageListener为第一步编写的类。分别在setTimeUnit和setTriggerValue里面设置调度的周期单位和时间。
三、两者的区别及适用情况
对于方法一是推荐使用的,但是有时候我们可能需要在程序中来设置调度周期,但是方法一需要在liferay-portlet.xml里面将调度的周期和时间就固定了。我们需要做一下变通,如在新闻采集的自动采集的代码里面就使用的方法一,在liferay工程中的日程管理也是使用了此功能。此方法适用于下面情况
- 需要在程序中设置调度周期
- 但是对于时间的精确度需求不是非常高,可以有一定的误差
如新闻采集的自动采集,如果我们需要对一个网站进行新闻的自动采集,我们一般将这个周期设置成几个小时重复执行一次,我们可以在liferay-portlet.xml里面设置成这个调度是10分钟或者30分钟执行一次检查,这个时候我们在doReceive()里面调用的代码不是具体的执行采集的代码,而是检查现在的这个时间是否在下调度周期中,如果是则执行采集,如果不是则跳过。
对于方法二而言,适用于以下情况:
- 需要执行调度的代码不明确属于某一个portlet。
- 需要精确控制时间。
只要满足上面的任何一个条件,都适合使用方法二,方法二里面的调度时间可以从数据库中读取也可以从配置文件中读取。
你好,我在方法1中往liferay-portlet.xml添加scheduler-entry配置时提示XML错误。请问是要添加DTD吗?版本是6.1。谢谢。
你好,你的问题解决了吗?我也有这样的问题。
你好,我也是遇到这个问题 是不是还要配置什么东西。
位置放错就会报xml的错误了,下面是一个简单的例子:
Below is the code from Liferay-portlet.xml.
documentworkflowscheduler
/icon.png
This scheduler is used to run its own job
com.hello.workflow.scheduler.DocumentWorkFlowScheduler
10
minute
false
/css/main.css
/js/main.js
documentworkflowscheduler-portlet
scheduler-entry 放的位置有要求,不能乱放的。我放在/icon.png后面就可以了。