Oracle神谕

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  284 随笔 :: 9 文章 :: 106 评论 :: 0 Trackbacks

#

(org.jbpm.identity)身份包包含有如下几个类:
一、Entity 实体类:这个类作为users<用户>groups<组>和memberships<成员>的超类,用来管理名称和权限的增加删除和获取。其中用到了jdk的Permission类。目前还不知道这个对具体权限的控制有什么作用?
二、Group组类:这个类是Entity的继承子类,这个类主要用于区分层次组、安全角色和其他。  
  (1)主要包含以下几个Filed:
     protected String type = null;
     protected Group parent = null; //父就是自己
     protected Set children = null; //子是一个集合,其中的元素也是Group
     protected Set memberships = null; //会员
   (2)JBpm的类内部方法的命名还是很不错的:
    public Set getUsersForMembershipName(String membershipName) 很容易理解为通过membershipName来获得所有的用户。 这个内不仅仅是简单的JavaBean的setter和getter,而是进行一些引申的操作,例如获取用户以及addXXX等操作。
   (3)与之相对应的hibernate Mapping文件Group.hbm.xml其中也有几个地方,值得注意,其实这个在Jbpm中是大量使用的:
           table="JBPM_ID_GROUP"
         discriminator-value="G">
    ....
 
  这里表示的是在JBPM_ID_GROUP表中的CLASS_字段等于G的为Group的影射对象。这里我们在使用一个表的不同类型(一个字段对应不同的值)就可以表示不同的类型对象。这一点很值得我们学习的。其他值得我们关注的是它采用的集合类型的操作方式,在我们以前的开发中这种做法并值得采用的。
三、Membership成员类:它是用户和组之间的一个联系的桥梁。会员的名称代表角色的名称。一个会员可能是一个组织的位置,所以权限往往于会员联系。会员的名字能用来做角色的名字。不同的会员来担当不同的角色。
protected  String role = null;
protected Group group = null;
protected User user = null;
 这个类没有采用传统的构造子复用的方式,而是用很了很多的create()方法,有些方法让人感觉有些茫然不知所措,不过直接相关的代码,也就明白了。
  其中影射文件也使用了discriminator(鉴别者)的功能,以及many-to-one和set集合的做法
四、User类:包含有三个字段:password email  以及Set memeberships。
  以下是通过两种方式获得Groups的方法,一个是通过组的类别,一种是通过成员名称(角色名称)
  public Set getGroupsForGroupType(String groupType)
  public Set getGroupsForMembershipName(String membershipName)

  通过观察,我们发现这里其实有以下几个对象:Entity Group Memebership User Permission。其中Group、Memebership、User都是Entity都是子类和父类的关系。Entity和Permission是一对多的关系,表示一个实体拥有各种不同的权限,同样其他的Group等子类,也与Permission都是一对多的关系。Group 和Memeber是一对多的,一个组具有不同的角色(成员)。Membership与User和Group是多对一的关系。User和Membership之间是一对多的关系。

其中涉及的表有:
jbpm_id_group;
jbpm_id_membership;
jbpm_id_user;

posted @ 2005-09-17 21:33 java世界畅谈 阅读(1239) | 评论 (0)编辑 收藏

今天在看Jbpm的源代码中,发现其中的Hibernate中的PO的序列化对象基本上都有一个serialVersionUID的一个私有对象,就上网查找了一部分资料。
http://www.javapractices.com/Topic45.cjp
Guidelines for serialVersionUID : (serialVersionUID的指导纲要)

  • always include it as a field, for example: "private static final long serialVersionUID = 7526472295622776147L; " include this field even in the first version of the class, as a reminder(提示) of its importance
  • do not change the value of this field in future versions, unless you are knowingly(老练地) making changes to the class which will render(使..变成) it incompatible(不相容的) with old serialized objects
  • new versions of Serializable classes may or may not be able to read old serialized objects;  it depends upon the nature of the change; provide a pointer to Sun's guidelines for what constitutes a compatible(兼容地) change, as a convenience to future maintainers
posted @ 2005-09-17 21:15 java世界畅谈 阅读(493) | 评论 (0)编辑 收藏

 在网站中经常需要进行在线人数的统计。过去的一般做法是结合登录和退出功能,即当用户输入用户名密码进行登录的时候计数器加1,然后当用户点击退出按钮退出系统的时候计数器减1。这种处理方式存在一些缺点,例如:用户正常登录后,可能会忘记点击退出按钮,而直接关闭浏览器,导致计数器减1的操作没有及时执行;网站上还经常有一些内容是不需要登录就可以访问的,在这种情况下也无法使用上面的方法进行在线人数统计。
  我们可以利用Servlet规范中定义的事件监听器(Listener)来解决这个问题,实现更准确的在线人数统计功能。对每一个正在访问的用户,J2EE应用服务器会为其建立一个对应的HttpSession对象。当一个浏览器第一次访问网站的时候,J2EE应用服务器会新建一个HttpSession对象,并触发HttpSession创建事件,如果注册了HttpSessionListener事件监听器,则会调用HttpSessionListener事件监听器的sessionCreated方法。相反,当这个浏览器访问结束超时的时候,J2EE应用服务器会销毁相应的HttpSession对象,触发HttpSession销毁事件,同时调用所注册HttpSessionListener事件监听器的sessionDestroyed方法。
  可见,对应于一个用户访问的开始和结束,相应的有sessionCreated方法和sessionDestroyed方法执行。这样,我们只需要在HttpSessionListener实现类的sessionCreated方法中让计数器加1,在sessionDestroyed方法中让计数器减1,就轻松实现了网站在线人数的统计功能。
  下面就是利用HttpSessionListener实现在线人数统计的一个例子,这个例子已经在中创软件的J2EE应用服务器InforWeb中测试通过。
  首先,编写一个简单的计数器,代码如下:
  1. package gongfei.cmc.articles.onlinecounter;
  2. public class OnlineCounter {
  3.     private static long online = 0;    
  4.     public static long getOnline() {
  5.         return online;
  6.     }    
  7.     public static void raise(){
  8.         online++;
  9.     } 
  10.     public static void reduce(){
  11.         online--;
  12.    }
  13. }

  然后,编写HttpSessionListener实现类,在这个实现类的sessionCreated方法中调用OnlineCounter的raise方法,在sessionDestroyed方法中调用OnlineCounter的reduce方法,代码如下:
  1. package gongfei.cmc.articles.onlinecounter;
  2. import javax.servlet.http.HttpSessionEvent;
  3. import javax.servlet.http.HttpSessionListener;
  4. public class OnlineCounterListener implements HttpSessionListener {
  5.     public void sessionCreated(HttpSessionEvent hse) {
  6.         OnlineCounter.raise();
  7.     }
  8.     public void sessionDestroyed(HttpSessionEvent hse) {
  9.         OnlineCounter.reduce();
  10.     }
  11. }

  再然后,把这个HttpSessionListener实现类注册到网站应用中,也就是在网站应用的web.xml中加入如下内容:
  1. <web-app>
  2.     ……
  3.     <listener>
  4.         <listener-class>
  5.             gongfei.cmc.articles.example.OnlineCounterListener
  6.         </listener-class>
  7.     </listener>
  8.     ……
  9. </web-app>


原文地址:http://www.javaresearch.org/article/showarticle.jsp?column=106&thread=18541

posted @ 2005-09-12 16:06 java世界畅谈 阅读(1000) | 评论 (1)编辑 收藏

  很长时间也没有下Blog了,今天是周末。在家里休息,就随手写点东西了。这一阵是比较忙碌,时间都过的很是紧凑,没有多余的时间来写blog,也没有学习什么新的东西。不过因为,公司现在采用JDK5.0的语法,琢磨了枚举类型和泛型,也看看了不定参数已经自动装箱等等功能。有些功能确实不错,不过一下子还是不太适应。
  自动装拆箱不错,基本数据类型和java类型可以自己进行转换,不需要特意进行转换。
  枚举感觉用得不是很多的,当然在特定环境下,这个还是有些作用的。
  其实很多时间都在琢磨泛型。这东西很是不错,以后不用在一次次进行转型,不过现在还在新老代码的更替中,新老代码同时并存。
  不定参数也有点意思。以后不用丢set或者map等等接口了。

posted @ 2005-09-11 11:43 java世界畅谈 阅读(165) | 评论 (1)编辑 收藏

About
--------------------------------------------------------------------------------

What is it?  它是什么?

Mantis is a web-based bugtracking system. It is written in the PHP scripting language and

requires the MySQL database and a webserver. Mantis has been installed on Windows, MacOS,

OS/2, and a variety of Unix operating systems. Almost any web browser should be able to

function as a client. It is released under the terms of the GNU General Public License

(GPL).
Nantis 是一个基于web bug追踪系统。它使用php脚本语言和需要Mysql 数据库和一个web服务器。Mantis

已经被安装在Windows、MacOS、OS/2和各种各样Unix操作系统中。几乎所有的web浏览器应该可以做为一

个客户端功能。它被在GNU通用公共license(GNU)下发布。

Mantis is free to use and modify. It is free to redistribute as long as you abide by the
distribution terms of the GPL.

Mantis是免费使用和修改的。它是在GPL原则下可以被重新修改分配的。

History 历史

Mantis started as an internal bug tracking tool for a pet project (video game). Good, free

packages were lacking at the time so a bugtracker was written. Since then, Mantis has been

totally re-written and make it available to the public.

Mantis开始作为一个为pet项目(视频游戏)的内部bug追踪工具。免费的包缺少在时间,所以bug追踪被

写出。从那以后,mantis被重新编写并且将它公布与众。

Goals 目标

The goals for this project are to produce and maintain a lightweight and simple bugtracking

system. Additions of complexity and/or features are modular and configurable so that users

can be shielded from unwanted clutter.

这个项目的目标是产生和维护一个高亮度并且简单的bug追踪系统。复杂的附加特征被模块化并且被注册

这样,用户可以避免不想要的混乱。

The product is designed to be easily modifiable, customizable, and upgradeable. Anyone with

intermediate PHP and MySQL experience should be able to customize Mantis to suit their

needs.

这个产品被设计成很容易修改,可定制、和可升级的。伴随Php和MySQL经验的任何人应该可以定制Mantis

来满足他们的需要。

Features and Benefits 特性和用处


Free  免费
Easy installation  容易安装
Web based   基于web
Platform independent  平台独立
Multiple projects   多项目
Multiple languages  多语言
Emailing     邮件
Simple Search  简单搜索
Viewing filters   过滤显示
PHP    php

 

Upcoming Features 将来的特征

Check the Roadmap for a more detailed and sometimes up to date list of items.

Versioning

The release numbering convention used is major.minor.micro (eg. 0.18.2).

Major - Indicates a very large change in the core package. Rewrites or major milestones.
Minor - Significant amount of feature addition/modification.
Micro - Usually bug fixes or minor features
How to Help


Report real bugs to the Development Bugtracker
Suggest (reasonable) features
Contribute code or tell us where to look.
Let us know if you find it useful. We won't publish the information without permission, but

we appreciate the feedback!

posted @ 2005-08-05 17:30 java世界畅谈 阅读(1149) | 评论 (1)编辑 收藏

Sending Email with Spring mail abstraction layer
使用Spring邮件抽象层发送邮件:
18.1. Introduction
介绍
Spring provides a higher level of abstraction for sending electronic mail which shields the user from the specifics of underlying mailing system and is responsible for a low level resource handling on behalf of the client.

Spring 支持一个更高层的抽象用来发送电子邮件,它隐藏底层邮件系统的细节并且代表客户端对低级别的控制 。

18.2. Spring mail abstraction structure
Spring邮件抽象结构
The main package of Spring mail abstraction layer is org.springframework.mail package. It contains central interface for sending emails called MailSender and the value object which encapsulates properties of a simple mail such as from, to, cc, subject, text called SimpleMailMessage. This package also contains a hierarchy of checked exceptions which provide a higher level of abstraction over the lower level mail system exceptions with the root exception being MailException.Please refer to JavaDocs for more information on mail exception hierarchy.

Sring邮件抽象层的主要包是:org.springframework.mail 包。它包含叫MailSender为发送邮件的核心接口和包含简单邮件属性例如from,to,cc,subject,text叫SimpleMailMessage的值对象. 这个包也包含一个检查异常的层次,它支持一个更高级别的抽象超过低级别的邮件系统异常伴随根异常存在MailException. 请参考JavaDocs为更多的信息杂邮件异常层次。

Spring also provides a sub-interface of MailSender for specialized JavaMail features such as MIME messages, namely org.springframework.mail.javamail.JavaMailSender It also provides a callback interface for preparation of JavaMail MIME messages, namely org.springframework.mail.javamail.MimeMessagePreparator

Spring也支持一个MailSender的专用于JavaMail特征例如MIME消息子接口,命名为org.springframework.javamail.JavaMailerSener。它也支持一个为JavaMail MIME信息的准备回调接口,命名为org.springframework.mail.JavaMail.MimeMessagePreparator.

MailSender:

public interface MailSender {

    /**
     * Send the given simple mail message.
     * @param simpleMessage message to send
     * @throws MailException in case of message, authentication, or send errors
     * 发送给定的简单邮件信息
     * @参数 simpleMessage  发送的信息
     * @throws MailException 假设信息,证明或发送错误
     */
    
    public void send(SimpleMailMessage simpleMessage) throws MailException;

    /**
     * Send the given array of simple mail messages in batch.
     * @param simpleMessages messages to send
     * @throws MailException in case of message, authentication, or send errors
     */
    public void send(SimpleMailMessage[] simpleMessages) throws MailException;

}

JavaMailSender:

public interface JavaMailSender extends MailSender {

    /**
     * Create a new JavaMail MimeMessage for the underlying JavaMail Session
     * of this sender. Needs to be called to create MimeMessage instances
     * that can be prepared by the client and passed to send(MimeMessage).
     * @return the new MimeMessage instance
     * @see #send(MimeMessage)
     * @see #send(MimeMessage[])
     * 创建一个新的JavaMail MimeMessage 为潜在的JavaMail的发送者的会话.
     * 需要被调用来创建MimeMessage实例,它可以被客户准备并且被传递发送(MimeMessage).
     * @return 这个新的MimeMessage 实例
     * @see #send(Message)
     * @sess #send(MimeMessage[])
     */
    public MimeMessage createMimeMessage();

    /**
     * Send the given JavaMail MIME message.
     * The message needs to have been created with createMimeMessage.
     * @param mimeMessage message to send
     * @throws MailException in case of message, authentication, or send errors
     * @see #createMimeMessage
     */
    public void send(MimeMessage mimeMessage) throws MailException;

    /**
     * Send the given array of JavaMail MIME messages in batch.
     * The messages need to have been created with createMimeMessage.
     * @param mimeMessages messages to send
     * @throws MailException in case of message, authentication, or send errors
     * @see #createMimeMessage
     */
    public void send(MimeMessage[] mimeMessages) throws MailException;

    /**
     * Send the JavaMail MIME message prepared by the given MimeMessagePreparator.
     * Alternative way to prepare MimeMessage instances, instead of createMimeMessage
     * and send(MimeMessage) calls. Takes care of proper exception conversion.
     * @param mimeMessagePreparator the preparator to use
     * @throws MailException in case of message, authentication, or send errors
     */
    public void send(MimeMessagePreparator mimeMessagePreparator) throws MailException;

    /**
     * Send the JavaMail MIME messages prepared by the given MimeMessagePreparators.
     * Alternative way to prepare MimeMessage instances, instead of createMimeMessage
     * and send(MimeMessage[]) calls. Takes care of proper exception conversion.
     * @param mimeMessagePreparators the preparator to use
     * @throws MailException in case of message, authentication, or send errors
     */
    public void send(MimeMessagePreparator[] mimeMessagePreparators) throws MailException;

}
MimeMessagePreparator:

public interface MimeMessagePreparator {

    /**
     * Prepare the given new MimeMessage instance.
     * @param mimeMessage the message to prepare
     * @throws MessagingException passing any exceptions thrown by MimeMessage
     * methods through for automatic conversion to the MailException hierarchy
     */
    void prepare(MimeMessage mimeMessage) throws MessagingException;

}

18.3. Using Spring mail abstraction
使用Spring邮件抽象
Let's assume there is a business interface called OrderManager
让我们假定这里有一个商业接口叫OrderManager

public interface OrderManager {

    void placeOrder(Order order);
   
}

and there is a use case that says that an email message with order number would need to be generated and sent to a customer placing that order. So for this purpose we want to use MailSender and SimpleMailMessage
并且这里有一个有用案例,可以说一个伴随订单编号的邮件信息将需要被产生并且发送给一个客户处理这个订单。所以为这个目的我们想要使用MailSender和SimpleMailSender.


Please note that as usual, we work with interfaces in the business code and let Spring IoC container take care of wiring of all the collaborators for us.

请注意照常,我们工作使用在商业代码中的接口并且让Spring Ioc 容器关心为我们的所有合作者。

Here is the implementation of OrderManager
这里是OrderManager的实现:

import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;

public class OrderManagerImpl implements OrderManager {

    private MailSender mailSender;
    private SimpleMailMessage message;

    public void setMailSender(MailSender mailSender) {
        this.mailSender = mailSender;
    }

    public void setMessage(SimpleMailMessage message) {
        this.message = message;
    }

    public void placeOrder(Order order) {

        //... * Do the business calculations....
        //... * Call the collaborators to persist the order

        //Create a thread safe "sandbox" of the message
        SimpleMailMessage msg = new SimpleMailMessage(this.message);
        msg.setTo(order.getCustomer().getEmailAddress());
        msg.setText(
            "Dear "
                + order.getCustomer().getFirstName()
                + order.getCustomer().getLastName()
                + ", thank you for placing order. Your order number is "
                + order.getOrderNumber());
        try{
            mailSender.send(msg);
        }
        catch(MailException ex) {
            //log it and go on
            System.err.println(ex.getMessage());           
        }
    }
}
Here is what the bean definitions for the code above would look like:
这里是这个为这个以上代码bean定义类似:

<bean id="mailSender"
      class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host"><value>mail.mycompany.com</value></property>
</bean>

<bean id="mailMessage"
      class="org.springframework.mail.SimpleMailMessage">
    <property name="from"><value>customerservice@mycompany.com</value></property>
    <property name="subject"><value>Your order</value></property>
</bean>

<bean id="orderManager"
      class="com.mycompany.businessapp.support.OrderManagerImpl">
    <property name="mailSender"><ref bean="mailSender"/></property>
    <property name="message"><ref bean="mailMessage"/></property>
</bean>
Here is the implementation of OrderManager using MimeMessagePreparator callback interface. Please note that the mailSender property is of type JavaMailSender in this case in order to be able to use JavaMail MimeMessage:

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import javax.mail.internet.MimeMessage;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessagePreparator;

public class OrderManagerImpl implements OrderManager {
    private JavaMailSender mailSender;
   
    public void setMailSender(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }

    public void placeOrder(final Order order) {

        //... * Do the business calculations....
        //... * Call the collaborators to persist the order
       
       
        MimeMessagePreparator preparator = new MimeMessagePreparator() {
            public void prepare(MimeMessage mimeMessage) throws MessagingException {
                mimeMessage.setRecipient(Message.RecipientType.TO,
                        new InternetAddress(order.getCustomer().getEmailAddress()));
                mimeMessage.setFrom(new InternetAddress("mail@mycompany.com"));
                mimeMessage.setText(
                    "Dear "
                        + order.getCustomer().getFirstName()
                        + order.getCustomer().getLastName()
                        + ", thank you for placing order. Your order number is "
                        + order.getOrderNumber());
            }
        };
        try{
            mailSender.send(preparator);
        }
        catch(MailException ex) {
            //log it and go on
            System.err.println(ex.getMessage());           
        }
    }
}
If you want to use JavaMail MimeMessage to the full power, the MimeMessagePreparator is available at your fingertips.
如果你想使用JavaMail  MimeMessage来使得足够强大,MimeMessagePreparator 是可以利用的。

Please note that the mail code is a crosscutting(横切的) concern(关注)  and is a perfect candidate(候选) for refactoring into a custom Spring AOP advice, which then could easily be applied to OrderManager target. Please see the AOP chapter.


18.3.1. Pluggable MailSender implementations
Spring comes with two MailSender implementations out of the box - the JavaMail implementation and the implementation on top of Jason Hunter's MailMessage class that's included in http://servlets.com/cos (com.oreilly.servlet). Please refer to JavaDocs for more information.

18.4. Using the JavaMail MimeMessageHelper
One of the components that comes in pretty handy when dealing with JavaMail messages is the org.springframework.mail.javamail.MimeMessageHelper. It prevents you from having to use the nasty APIs the the javax.mail.internet classes. A couple of possible scenarios:

18.4.1. Creating a simple MimeMessage and sending it
Using the MimeMessageHelper it's pretty easy to setup and send a MimeMessage:

// of course you would setup the mail sender using
// DI in any real-world cases
JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("mail.host.com");

MimeMessage message = sender.createMimeMesage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setTo("test@host.com");
helper.setText("Thank you for ordering!");

sender.send(message);

18.4.2. Sending attachments and inline resources
Email allow for attachments, but also for inline resources in multipart messages. Inline resources could for example be images or stylesheet you want to use in your message, but don't want displayed as attachment. The following shows you how to use the MimeMessageHelper to send an email along with an inline image.

JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("mail.host.com");

MimeMessage message = sender.createMimeMesage();

// use the true flag to indicate you need a multipart message
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setTo("test@host.com");

// use the true flag to indicate the text included is HTML
helper.setText(
  "<html><body><img src='cid:identifier1234'></body></html>"
  true);

// let's include the infamous windows Sample file (this time copied to c:/)
FileSystemResource res = new FileSystemResource(new File("c:/Sample.jpg"));
helper.addInline("identifier1234", res);

// if you would need to include the file as an attachment, use
// addAttachment() methods on the MimeMessageHelper

sender.send(message);
   
Inline resources are added to the mime message using the Content-ID specified as you've seen just now (identifier1234 in this case). The order in which you're adding the text and the resource are VERY important. First add the text and after that the resources. If you're doing it the other way around, it won't work!

 

posted @ 2005-07-25 11:32 java世界畅谈 阅读(882) | 评论 (3)编辑 收藏

Using the MethodInvokingJobDetailFactoryBean
使用MethodInvokingJobDetailFactoryBean
Often you just need to invoke a method on a specific object. Using the MethodInvokingJobDetailFactoryBean you can do exactly this:
经常地,你仅仅需要调用一个对象的一个方法。使用MethodInvokingJobDetailFactoryBean,你可以正确地这样做:

<bean id="methodInvokingJobDetail"
  class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <property name="targetObject"><ref bean="exampleBusinessObject"/></property>
    <property name="targetMethod"><value>doIt</value></property>
</bean>


The above example will result in the doIt being called on the exampleBusinessObject (see below):


public class BusinessObject {
 
  // properties and collaborators
 
  public void doIt() {
    // do the actual work
  }
}
   

<bean id="exampleBusinessObject" class="examples.ExampleBusinessObject"/>
   
Using the MethodInvokingJobDetailFactoryBean you don't need to create one-line jobs that just invoke a method, and you only need to create the actual business object and wire up the detail object.
使用MethodInvokingJobDetailFactoryBean 你不需要创建一个在线的jobs,仅仅调用它的方法,你可以仅仅只需要创建一个实际的逻辑对象并且把它绑定到细节对象。

By default, Quartz Jobs are stateless, resulting in the possibility of jobs interfering with each other. If you specify two triggers for the same JobDetail, it might be possible that before the first job has finished, the second one will start. If JobDetail objects implement the Stateful interface, this won't happen. The second job will not start before the first one has finished. To make jobs resulting from the MethodInvokingJobDetailFactoryBean non-concurrent, set the concurrent flag to false.

缺省地,Quartz jobs是无状态的,在jobs的可能性作为结果影响彼此。如果你限定两个触发器为同一个JohDetail,它在第一个job已经完成时是可能的,第二个将会开始。如果JobDetail实现了状态接口,它将不会发生。
<bean id="methodInvokingJobDetail"
  class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <property name="targetObject"><ref bean="exampleBusinessObject"/></property>
    <property name="targetMethod"><value>doIt</value></property>
    <property name="concurrent"><value>false</value></property>
</bean>
   
Note: By default, jobs will run in a concurrent fashion.

 

posted @ 2005-07-22 11:23 java世界畅谈 阅读(3116) | 评论 (0)编辑 收藏

 定时批处理作业是J2EE企业应用里很重要的一环,用来在晚间进行财务挂账,数据转存,新闻联播等等操作。

    而在Spring里,已经很好的集成了Quartz,简单到像配cron一样,在xml文件里面配一下时间就可以自动执行,不需要写一行代码。Spring对Quartz大刀阔斧的简化堪称范例,Quartz项目组也许可以学习一下。

    <bean id="methodInvokingJobDetail"
        class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject"><ref bean="financeDAO"/></property>
        <property name="targetMethod"><value>confirmOrder</value></property>
    </bean>

    <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="jobDetail">
            <ref bean="methodInvokingJobDetail"/>
        </property>
        <property name="cronExpression">
            <value>0 0 6,12,20 * * ?</value>
        </property>
    </bean>
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list><ref local="cronTrigger"/></list>
        </property>
    </bean>

上面这段配置文件规定了在早上6点和晚上8点执行financeDAO对象的confirmOrder()方法.


附:cronExpression配置说明

字段   允许值   允许的特殊字符
  0-59   , - * /
  0-59   , - * /
小时   0-23   , - * /
日期   1-31   , - * ? / L W C
月份   1-12 或者 JAN-DEC   , - * /
星期   1-7 或者 SUN-SAT   , - * ? / L C #
年(可选)   留空, 1970-2099   , - * /

posted @ 2005-07-20 21:37 java世界畅谈 阅读(15583) | 评论 (42)编辑 收藏

TriggerListeners and JobListeners
Listeners are objects that you create to perform actions based on events occuring within the scheduler. As you can probably guess, TriggerListeners receive events related to trigger,and JobListners receive events related to jobs.

Trigger-related events include: trigger firings,trigger mis-firings(discussed in the "Triggers" sections of this document),and trigger completions (the jobs fired off by the trigger is finished).

To create a listener,simply create an object the implements either the org.quartz.TriggerListener and/or org.quartz.JobListener interface. Listeners are then registered with the scheduler during run time ,and must be given a name(or rather ,they must advertise their own name via their getName()method.  Listeners can be registered as either "global" or "non-global". Global listeners receive events for ALL triggers/jobs, and non-global listeners receive events only for the specific triggers/jobs that explicitely name the listener in their getTriggerListenerNames() or getJobListenerNames() properties.

 scheduler.addGlobalJobListener(myJobListener);
or
 scheudler.addJobListener(myJobListener);
 
Listeners are not used by most users of Quartz,but are handy when application requirements create the need for the notification of events,without the Job itself explicitly nofifying the application.

posted @ 2005-07-20 21:27 java世界畅谈 阅读(407) | 评论 (0)编辑 收藏

More About CronTrigger
更多关于CronTrigger

CronTriggers are often more useful than SimpleTrigger, if you need a job-firing schedule that recurs based on calendar-like notions, rather than on the exactly specified intervals of SimpleTrigger.
CronTriggers 比SimpleTrigger经常更加有用,如果你需要一个基于像日历概念的重复 job-firing 调度,而不是在一个SimpleTrigger特定的间隔。

With CronTrigger, you can specify firing-schedules such as "every Friday at noon", or "every weekday and 9:30 am", or even "every 5 minutes between 9:00 am and 10:00 am on every Monday, Wednesday and Friday".
使用CronTrigger,你可以限定firing-schedulers例如 “每天中午“,或者”,”每天周日上午9:30“,或者甚至 “每5分钟在上午9:00 到 10:00 每周一、周三、周五”

Cron Expressions
Cron 表达式

Cron-Expressions are used to configure instances of CronTrigger. Cron-Expressions are strings that are actually made up of six sub-expressions, that describe individual details of the schedule. These sub-expression are separated with white-space, and represent:
Cron 表达式被用来注册CronTrigger实例的。Cron表达式是字符串,它由六个子表达式组成,它描述了不同的调度细节。这些子表达式被白色表达式隔开,表现:

Seconds  秒
Minutes  分
Hours    时
Day-of-Month  日
Month         月
Day-of-Week   周

An example of a complete cron-expression is the string "0 0 12 ? * WED" - which means "every Wednesday at 12:00 pm".
一个完整的Cron 表达式例子是字符串“0 0 12 ? * WEB” 意味着每周三上午12:00。

Individual sub-expressions can contain ranges and/or lists. For example, the day of week field in the previous (which reads "WED") example could be replaces with "MON-FRI", "MON, WED, FRI", or even "MON-WED,SAT".
单独的子表达式可以包含平行的 和/或。例如,在上一个例子一周的一天字段(它读作"WED")可以被“MON-FRI”,"MON,WED,FRI",或者甚至"MON-WED,SAT"替换掉。

Wild-cards (the '*' character) can be used to say "every" possible value of this field. Therefore the '*' character in the "Month" field of the previous example simply means "every month". A '*' in the Day-Of-Week field would obviously mean "every day of the week".
统配符("*"字符)可以被用来作为这个字段的"每一个"可能值。所以,在上一个例子月字段中的"*"字符表示每个月。 一个"*"在周天将明显意味着周的每一天。

All of the fields have a set of valid values that can be specified. These values should be fairly obvious - such as the numbers 0 to 59 for seconds and minutes, and the values 0 to 23 for hours. Day-of-Month can be any value 0-31, but you need to be careful about how many days are in a given month! Months can be specified as values between 0 and 11, or by using the strings JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC. Days-of-Week can be specified as vaules between 1 and 7 (1 = Sunday) or by using the strings SUN, MON, TUE, WED, THU, FRI and SAT.
所有字段都用一个合法限定的值。这些值应该是明显的,例如0到59数字为秒和分的限定,0到23为小时。月的某天可以是0-31的,或者你需要消息给个月有多少天!月份可以被限定在0到11,或者,使用英文字符串缩写。一个礼拜的一天可以被限定作为1到7(1=Sunnday)或者使用英文字符串。


The '/' character can be used to specify increments to values. For example, if you put '0/15' in the Minutes field, it means 'every 15 minutes, starting at minute zero'. If you used '3/20' in the Minutes field, it would mean 'every 20 minutes during the hour, starting at minute three' - or in other words it is the same as specifying '3,23,43' in the Minutes field.
"/"字符可以内用来限定值的增加。例如,如果你将'0/15'放到分钟字段,它意味着"每15分钟,开始于0分钟"。如果你使用"3/20"在分钟字段中,你将意味着"一个小时内每20分钟,开始于3分钟"---  或者换言之,它和在分钟字段"3,23,43"限定是一样的。


The '?' character is allowed for the day-of-month and day-of-week fields. It is used to specify "no specific value". This is useful when you need to specify something in one of the two fields, but not the other. See the examples below (and CronTrigger JavaDOC) for clarification.

"?"字符是允许为月的某一天或者周的某一天字段的。它被用来限定"没有限定值"。这是有用的,当你需要限定一些事情在一个或两个字段中,但不是这里的。

The 'L' character is allowed for the day-of-month and day-of-week fields. This character is short-hand for "last", but it has different meaning in each of the two fields. For example, the value "L" in the day-of-month field means "the last day of the month" - day 31 for January, day 28 for February on non-leap years. If used in the day-of-week field by itself, it simply means "7" or "SAT". But if used in the day-of-week field after another value, it means "the last xxx day of the month" - for example "6L" or "FRIL" both mean "the last friday of the month". When using the 'L' option, it is important not to specify lists, or ranges of values, as you'll get confusing results.

"L"字符是允许用来月某天和周某天字段。这个字符是一个"last"的缩写,但是它有不同的意义在两个字段的其中之一。例如,这个值"L"在月字段的某一天意味着" 这个月的最后一天",31或者28等等。

Here are a few more examples of expressions and their meanings - you can find even more in the JavaDOC for CronTrigger

CronTrigger Example 1 - an expression to create a trigger that simply fires every 5 minutes

  "0 0/5 * * * ?"

CronTrigger Example 2 - an expression to create a trigger that fires every 5 minutes, at 10 seconds after the minute (i.e. 10:00:10 am, 10:05:10 am, etc.).

  "10 0/5 * * * ?"

CronTrigger Example 3 - an expression to create a trigger that fires at 10:30, 11:30, 12:30, and 13:30, on every Wednesday and Friday.

  "0 30 10-13 ? * WED,FRI"

CronTrigger Example 4 - an expression to create a trigger that fires every half hour between the hours of 8 am and 10 am on the 5th and 20th of every month. Note that the trigger will NOT fire at 10:00 am, just at 8:00, 8:30, 9:00 and 9:30

  "0 0/30 8-9 5,20 * ?"

Note that some scheduling requirements are too complicated to express with a single trigger - such as "every 5 minutes between 9:00 am and 10:00 am, and every 20 minutes between 1:00 pm and 10:00 pm". The solution in this scenario is to simply create two triggers, and register both of them to run the same job.

posted @ 2005-07-20 15:25 java世界畅谈 阅读(1316) | 评论 (0)编辑 收藏

仅列出标题
共29页: First 上一页 21 22 23 24 25 26 27 28 29 下一页