﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-java神谕-随笔分类-Spring</title><link>http://www.blogjava.net/javaora/category/1829.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 10:49:46 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 10:49:46 GMT</pubDate><ttl>60</ttl><item><title>再看JPetstore所想到的</title><link>http://www.blogjava.net/javaora/archive/2005/10/19/16065.html</link><dc:creator>java世界畅谈</dc:creator><author>java世界畅谈</author><pubDate>Wed, 19 Oct 2005 15:47:00 GMT</pubDate><guid>http://www.blogjava.net/javaora/archive/2005/10/19/16065.html</guid><wfw:comment>http://www.blogjava.net/javaora/comments/16065.html</wfw:comment><comments>http://www.blogjava.net/javaora/archive/2005/10/19/16065.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/javaora/comments/commentRss/16065.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaora/services/trackbacks/16065.html</trackback:ping><description><![CDATA[<P>　　这些天在细看《J2EE Development without EJB》书，感受颇多。说起来做J2EE方面开发也有几年，自己认为自己还是有一定实力的。但是看完以后，再针对我们项目的开发感觉很多地方做的确实有很多问题。因为一直都这样做，没有人提出异议。闷着头做事情，有时候确实不好，要交流，特别是要倾听那些经验丰富的前辈的教诲。<BR>　　OO，接触开发也这么多年了，确实很少有项目，真正做到OO的。看看我们的项目，POJO做成伪对象，只是负责了值的传递，只有可怜的setter和getter，其中没有任何业务逻辑操作的代码（没有任何行为）。我们所谓的业务逻辑是引入一个Manager进行综合处理。<BR>　　１年前，也是看了jPetStore收益很多。今天再次看这个代码。又引发了更多的思考。<BR>　　先看jPetstore的处理：<BR>　　在org.springframework.sample.jpetstore包中：<BR>　　Account类：比较简单，普通的JavaBean。<BR>　　Cart类和CarItem类：从关系模型中，可以看到这是一个主从关系的对象。其中Cart（购物车）中有不少行为。例如：新增、删除购物车项目；计算总金额。一般来说，我们项目中一般这样的逻辑是写在Manager类中的。<BR>　　在Order类中，也采用一些业务行为，例如初始化订单等等。<BR>　　</P><img src ="http://www.blogjava.net/javaora/aggbug/16065.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaora/" target="_blank">java世界畅谈</a> 2005-10-19 23:47 <a href="http://www.blogjava.net/javaora/archive/2005/10/19/16065.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Spring邮件抽象层发送邮件</title><link>http://www.blogjava.net/javaora/archive/2005/07/25/8386.html</link><dc:creator>java世界畅谈</dc:creator><author>java世界畅谈</author><pubDate>Mon, 25 Jul 2005 03:32:00 GMT</pubDate><guid>http://www.blogjava.net/javaora/archive/2005/07/25/8386.html</guid><wfw:comment>http://www.blogjava.net/javaora/comments/8386.html</wfw:comment><comments>http://www.blogjava.net/javaora/archive/2005/07/25/8386.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/javaora/comments/commentRss/8386.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaora/services/trackbacks/8386.html</trackback:ping><description><![CDATA[<P>Sending Email with Spring mail abstraction layer<BR>使用Spring邮件抽象层发送邮件：<BR>18.1. Introduction<BR>介绍<BR>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.</P>
<P>Spring 支持一个更高层的抽象用来发送电子邮件，它隐藏底层邮件系统的细节并且代表客户端对低级别的控制 。</P>
<P>18.2. Spring mail abstraction structure<BR>Spring邮件抽象结构<BR>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.</P>
<P>Sring邮件抽象层的主要包是：org.springframework.mail 包。它包含叫MailSender为发送邮件的核心接口和包含简单邮件属性例如from,to,cc,subject,text叫SimpleMailMessage的值对象. 这个包也包含一个检查异常的层次，它支持一个更高级别的抽象超过低级别的邮件系统异常伴随根异常存在MailException. 请参考JavaDocs为更多的信息杂邮件异常层次。</P>
<P>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</P>
<P>Spring也支持一个MailSender的专用于JavaMail特征例如MIME消息子接口，命名为org.springframework.javamail.JavaMailerSener。它也支持一个为JavaMail MIME信息的准备回调接口，命名为org.springframework.mail.JavaMail.MimeMessagePreparator.</P>
<P>MailSender: </P>
<P>public interface MailSender {</P>
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * Send the given simple mail message.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param simpleMessage message to send<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @throws MailException in case of message, authentication, or send errors<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 发送给定的简单邮件信息<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @参数 simpleMessage&nbsp; 发送的信息<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @throws MailException 假设信息，证明或发送错误<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; public void send(SimpleMailMessage simpleMessage) throws MailException;</P>
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * Send the given array of simple mail messages in batch.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param simpleMessages messages to send<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @throws MailException in case of message, authentication, or send errors<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public void send(SimpleMailMessage[] simpleMessages) throws MailException;</P>
<P>}</P>
<P>JavaMailSender: </P>
<P>public interface JavaMailSender extends MailSender {</P>
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * Create a new JavaMail MimeMessage for the underlying JavaMail Session<BR>&nbsp;&nbsp;&nbsp;&nbsp; * of this sender. Needs to be called to create MimeMessage instances<BR>&nbsp;&nbsp;&nbsp;&nbsp; * that can be prepared by the client and passed to send(MimeMessage).<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @return the new MimeMessage instance<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @see #send(MimeMessage)<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @see #send(MimeMessage[])<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 创建一个新的JavaMail MimeMessage 为潜在的JavaMail的发送者的会话.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * 需要被调用来创建MimeMessage实例，它可以被客户准备并且被传递发送(MimeMessage).<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @return 这个新的MimeMessage 实例<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @see #send(Message)<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @sess #send(MimeMessage[])<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public MimeMessage createMimeMessage();</P>
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * Send the given JavaMail MIME message.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * The message needs to have been created with createMimeMessage.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param mimeMessage message to send<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @throws MailException in case of message, authentication, or send errors<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @see #createMimeMessage<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public void send(MimeMessage mimeMessage) throws MailException;</P>
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * Send the given array of JavaMail MIME messages in batch.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * The messages need to have been created with createMimeMessage.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param mimeMessages messages to send<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @throws MailException in case of message, authentication, or send errors<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @see #createMimeMessage<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public void send(MimeMessage[] mimeMessages) throws MailException;</P>
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * Send the JavaMail MIME message prepared by the given MimeMessagePreparator.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * Alternative way to prepare MimeMessage instances, instead of createMimeMessage<BR>&nbsp;&nbsp;&nbsp;&nbsp; * and send(MimeMessage) calls. Takes care of proper exception conversion.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param mimeMessagePreparator the preparator to use<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @throws MailException in case of message, authentication, or send errors<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public void send(MimeMessagePreparator mimeMessagePreparator) throws MailException;</P>
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * Send the JavaMail MIME messages prepared by the given MimeMessagePreparators.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * Alternative way to prepare MimeMessage instances, instead of createMimeMessage<BR>&nbsp;&nbsp;&nbsp;&nbsp; * and send(MimeMessage[]) calls. Takes care of proper exception conversion.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param mimeMessagePreparators the preparator to use<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @throws MailException in case of message, authentication, or send errors<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; public void send(MimeMessagePreparator[] mimeMessagePreparators) throws MailException;</P>
<P>}<BR>MimeMessagePreparator: </P>
<P>public interface MimeMessagePreparator {</P>
<P>&nbsp;&nbsp;&nbsp; /**<BR>&nbsp;&nbsp;&nbsp;&nbsp; * Prepare the given new MimeMessage instance.<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @param mimeMessage the message to prepare<BR>&nbsp;&nbsp;&nbsp;&nbsp; * @throws MessagingException passing any exceptions thrown by MimeMessage<BR>&nbsp;&nbsp;&nbsp;&nbsp; * methods through for automatic conversion to the MailException hierarchy<BR>&nbsp;&nbsp;&nbsp;&nbsp; */<BR>&nbsp;&nbsp;&nbsp; void prepare(MimeMessage mimeMessage) throws MessagingException;</P>
<P>}</P>
<P>18.3. Using Spring mail abstraction<BR>使用Spring邮件抽象<BR>Let's assume there is a business interface called OrderManager<BR>让我们假定这里有一个商业接口叫OrderManager</P>
<P>public interface OrderManager {</P>
<P>&nbsp;&nbsp;&nbsp; void placeOrder(Order order);<BR>&nbsp;&nbsp;&nbsp; <BR>}</P>
<P>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<BR>并且这里有一个有用案例，可以说一个伴随订单编号的邮件信息将需要被产生并且发送给一个客户处理这个订单。所以为这个目的我们想要使用MailSender和SimpleMailSender.</P>
<P><BR>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.</P>
<P>请注意照常，我们工作使用在商业代码中的接口并且让Spring Ioc 容器关心为我们的所有合作者。</P>
<P>Here is the implementation of OrderManager <BR>这里是OrderManager的实现:</P>
<P>import org.springframework.mail.MailException;<BR>import org.springframework.mail.MailSender;<BR>import org.springframework.mail.SimpleMailMessage;</P>
<P>public class OrderManagerImpl implements OrderManager {</P>
<P>&nbsp;&nbsp;&nbsp; private MailSender mailSender;<BR>&nbsp;&nbsp;&nbsp; private SimpleMailMessage message;</P>
<P>&nbsp;&nbsp;&nbsp; public void setMailSender(MailSender mailSender) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.mailSender = mailSender;<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; public void setMessage(SimpleMailMessage message) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.message = message;<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; public void placeOrder(Order order) {</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //... * Do the business calculations....<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //... * Call the collaborators to persist the order</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Create a thread safe "sandbox" of the message<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SimpleMailMessage msg = new SimpleMailMessage(this.message);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; msg.setTo(order.getCustomer().getEmailAddress());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; msg.setText(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Dear "<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + order.getCustomer().getFirstName()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + order.getCustomer().getLastName()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + ", thank you for placing order. Your order number is "<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + order.getOrderNumber());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mailSender.send(msg);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(MailException ex) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //log it and go on<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println(ex.getMessage());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>}<BR>Here is what the bean definitions for the code above would look like:<BR>这里是这个为这个以上代码bean定义类似：</P>
<P>&lt;bean id="mailSender"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.mail.javamail.JavaMailSenderImpl"&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;property name="host"&gt;&lt;value&gt;mail.mycompany.com&lt;/value&gt;&lt;/property&gt;<BR>&lt;/bean&gt;</P>
<P>&lt;bean id="mailMessage"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.mail.SimpleMailMessage"&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;property name="from"&gt;&lt;value&gt;customerservice@mycompany.com&lt;/value&gt;&lt;/property&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;property name="subject"&gt;&lt;value&gt;Your order&lt;/value&gt;&lt;/property&gt;<BR>&lt;/bean&gt;</P>
<P>&lt;bean id="orderManager"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="com.mycompany.businessapp.support.OrderManagerImpl"&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;property name="mailSender"&gt;&lt;ref bean="mailSender"/&gt;&lt;/property&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;property name="message"&gt;&lt;ref bean="mailMessage"/&gt;&lt;/property&gt;<BR>&lt;/bean&gt;<BR>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: </P>
<P>import javax.mail.Message;<BR>import javax.mail.MessagingException;<BR>import javax.mail.internet.InternetAddress;<BR>import javax.mail.internet.MimeMessage;</P>
<P>import javax.mail.internet.MimeMessage;<BR>import org.springframework.mail.MailException;<BR>import org.springframework.mail.javamail.JavaMailSender;<BR>import org.springframework.mail.javamail.MimeMessagePreparator;</P>
<P>public class OrderManagerImpl implements OrderManager {<BR>&nbsp;&nbsp;&nbsp; private JavaMailSender mailSender;<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; public void setMailSender(JavaMailSender mailSender) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.mailSender = mailSender;<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; public void placeOrder(final Order order) {</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //... * Do the business calculations....<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //... * Call the collaborators to persist the order<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MimeMessagePreparator preparator = new MimeMessagePreparator() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void prepare(MimeMessage mimeMessage) throws MessagingException {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mimeMessage.setRecipient(Message.RecipientType.TO, <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new InternetAddress(order.getCustomer().getEmailAddress()));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mimeMessage.setFrom(new InternetAddress("<A href="mailto:mail@mycompany.com">mail@mycompany.com</A>"));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mimeMessage.setText(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Dear "<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + order.getCustomer().getFirstName()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + order.getCustomer().getLastName()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + ", thank you for placing order. Your order number is "<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + order.getOrderNumber());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mailSender.send(preparator);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(MailException ex) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //log it and go on<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.err.println(ex.getMessage());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>}<BR>If you want to use JavaMail MimeMessage to the full power, the MimeMessagePreparator is available at your fingertips.<BR>如果你想使用JavaMail&nbsp; MimeMessage来使得足够强大，MimeMessagePreparator 是可以利用的。</P>
<P>Please note that the mail code is a crosscutting（横切的） concern（关注）&nbsp; 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.</P>
<P><BR>18.3.1. Pluggable MailSender implementations<BR>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 <A href="http://servlets.com/cos">http://servlets.com/cos</A> (com.oreilly.servlet). Please refer to JavaDocs for more information.</P>
<P>18.4. Using the JavaMail MimeMessageHelper<BR>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: </P>
<P>18.4.1. Creating a simple MimeMessage and sending it<BR>Using the MimeMessageHelper it's pretty easy to setup and send a MimeMessage: </P>
<P>// of course you would setup the mail sender using <BR>// DI in any real-world cases<BR>JavaMailSenderImpl sender = new JavaMailSenderImpl();<BR>sender.setHost("mail.host.com");</P>
<P>MimeMessage message = sender.createMimeMesage();<BR>MimeMessageHelper helper = new MimeMessageHelper(message);<BR>helper.setTo("<A href="mailto:test@host.com">test@host.com</A>");<BR>helper.setText("Thank you for ordering!");</P>
<P>sender.send(message);</P>
<P>18.4.2. Sending attachments and inline resources<BR>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. </P>
<P>JavaMailSenderImpl sender = new JavaMailSenderImpl();<BR>sender.setHost("mail.host.com");</P>
<P>MimeMessage message = sender.createMimeMesage();</P>
<P>// use the true flag to indicate you need a multipart message<BR>MimeMessageHelper helper = new MimeMessageHelper(message, true);<BR>helper.setTo("<A href="mailto:test@host.com">test@host.com</A>");</P>
<P>// use the true flag to indicate the text included is HTML<BR>helper.setText(<BR>&nbsp; "&lt;html&gt;&lt;body&gt;&lt;img src='cid:identifier1234'&gt;&lt;/body&gt;&lt;/html&gt;"<BR>&nbsp; true);</P>
<P>// let's include the infamous windows Sample file (this time copied to c:/)<BR>FileSystemResource res = new FileSystemResource(new File("c:/Sample.jpg"));<BR>helper.addInline("identifier1234", res);</P>
<P>// if you would need to include the file as an attachment, use<BR>// addAttachment() methods on the MimeMessageHelper</P>
<P>sender.send(message);<BR>&nbsp;&nbsp;&nbsp;<BR>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! </P>
<P>&nbsp;</P><img src ="http://www.blogjava.net/javaora/aggbug/8386.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaora/" target="_blank">java世界畅谈</a> 2005-07-25 11:32 <a href="http://www.blogjava.net/javaora/archive/2005/07/25/8386.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用MethodInvokingJobDetailFactoryBean</title><link>http://www.blogjava.net/javaora/archive/2005/07/22/8176.html</link><dc:creator>java世界畅谈</dc:creator><author>java世界畅谈</author><pubDate>Fri, 22 Jul 2005 03:23:00 GMT</pubDate><guid>http://www.blogjava.net/javaora/archive/2005/07/22/8176.html</guid><wfw:comment>http://www.blogjava.net/javaora/comments/8176.html</wfw:comment><comments>http://www.blogjava.net/javaora/archive/2005/07/22/8176.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaora/comments/commentRss/8176.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaora/services/trackbacks/8176.html</trackback:ping><description><![CDATA[<P>Using the MethodInvokingJobDetailFactoryBean<BR>使用MethodInvokingJobDetailFactoryBean<BR>Often you just need to invoke a method on a specific object. Using the MethodInvokingJobDetailFactoryBean you can do exactly this: <BR>经常地，你仅仅需要调用一个对象的一个方法。使用MethodInvokingJobDetailFactoryBean,你可以正确地这样做：</P>
<P>&lt;bean id="methodInvokingJobDetail" <BR>&nbsp; class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;property name="targetObject"&gt;&lt;ref bean="exampleBusinessObject"/&gt;&lt;/property&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;property name="targetMethod"&gt;&lt;value&gt;doIt&lt;/value&gt;&lt;/property&gt;<BR>&lt;/bean&gt;</P>
<P><BR>The above example will result in the doIt being called on the exampleBusinessObject (see below): </P>
<P><BR>public class BusinessObject {<BR>&nbsp; <BR>&nbsp; // properties and collaborators<BR>&nbsp; <BR>&nbsp; public void doIt() {<BR>&nbsp;&nbsp;&nbsp; // do the actual work<BR>&nbsp; }<BR>}<BR>&nbsp;&nbsp;&nbsp;</P>
<P>&lt;bean id="exampleBusinessObject" class="examples.ExampleBusinessObject"/&gt;<BR>&nbsp;&nbsp;&nbsp;<BR>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. <BR>使用MethodInvokingJobDetailFactoryBean 你不需要创建一个在线的jobs，仅仅调用它的方法，你可以仅仅只需要创建一个实际的逻辑对象并且把它绑定到细节对象。</P>
<P>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. </P>
<P>缺省地，Quartz jobs是无状态的，在jobs的可能性作为结果影响彼此。如果你限定两个触发器为同一个JohDetail,它在第一个job已经完成时是可能的，第二个将会开始。如果JobDetail实现了状态接口，它将不会发生。<BR>&lt;bean id="methodInvokingJobDetail"<BR>&nbsp; class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;property name="targetObject"&gt;&lt;ref bean="exampleBusinessObject"/&gt;&lt;/property&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;property name="targetMethod"&gt;&lt;value&gt;doIt&lt;/value&gt;&lt;/property&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;property name="concurrent"&gt;&lt;value&gt;false&lt;/value&gt;&lt;/property&gt;<BR>&lt;/bean&gt;<BR>&nbsp;&nbsp;&nbsp;<BR>Note: By default, jobs will run in a concurrent fashion. </P>
<P>&nbsp;</P><img src ="http://www.blogjava.net/javaora/aggbug/8176.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaora/" target="_blank">java世界畅谈</a> 2005-07-22 11:23 <a href="http://www.blogjava.net/javaora/archive/2005/07/22/8176.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring--简单使用quartz实现定时作业 </title><link>http://www.blogjava.net/javaora/archive/2005/07/20/8070.html</link><dc:creator>java世界畅谈</dc:creator><author>java世界畅谈</author><pubDate>Wed, 20 Jul 2005 13:37:00 GMT</pubDate><guid>http://www.blogjava.net/javaora/archive/2005/07/20/8070.html</guid><wfw:comment>http://www.blogjava.net/javaora/comments/8070.html</wfw:comment><comments>http://www.blogjava.net/javaora/archive/2005/07/20/8070.html#Feedback</comments><slash:comments>22</slash:comments><wfw:commentRss>http://www.blogjava.net/javaora/comments/commentRss/8070.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaora/services/trackbacks/8070.html</trackback:ping><description><![CDATA[&nbsp;定时批处理作业是J2EE企业应用里很重要的一环，用来在晚间进行财务挂账，数据转存，新闻联播等等操作。
<P>&nbsp;&nbsp;&nbsp; 而在Spring里，已经很好的集成了Quartz，简单到像配cron一样，在xml文件里面配一下时间就可以自动执行，不需要写一行代码。Spring对Quartz大刀阔斧的简化堪称范例，Quartz项目组也许可以学习一下。</P><PRE>&nbsp;&nbsp;&nbsp; &lt;bean id="methodInvokingJobDetail"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="targetObject"&gt;&lt;ref bean="financeDAO"/&gt;&lt;/property&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="targetMethod"&gt;&lt;value&gt;confirmOrder&lt;/value&gt;&lt;/property&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/bean&gt;</PRE><PRE><BR>&nbsp;&nbsp;&nbsp; &lt;bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="jobDetail"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ref bean="methodInvokingJobDetail"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="cronExpression"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;0 0 6,12,20 * * ?&lt;/value&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/bean&gt;</PRE><PRE>&nbsp;&nbsp;&nbsp; &lt;bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="triggers"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;list&gt;&lt;ref local="cronTrigger"/&gt;&lt;/list&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/bean&gt;</PRE>
<P>上面这段配置文件规定了在早上6点和晚上8点执行financeDAO对象的confirmOrder()方法.<BR></P>
<P><BR>附：cronExpression配置说明</P>
<P>
<TABLE cellSpacing=8>
<TBODY>
<TR>
<TH align=left>字段</TH>
<TH align=left>&nbsp;</TH>
<TH align=left>允许值</TH>
<TH align=left>&nbsp;</TH>
<TH align=left>允许的特殊字符</TH></TR>
<TR>
<TD align=left><CODE>秒</CODE></TD>
<TD align=left>&nbsp; </TD>
<TD align=left><CODE>0-59</CODE></TD>
<TD align=left>&nbsp; </TD>
<TD align=left><CODE>, - * /</CODE></TD></TR>
<TR>
<TD align=left><CODE>分</CODE></TD>
<TD align=left>&nbsp; </TD>
<TD align=left><CODE>0-59</CODE></TD>
<TD align=left>&nbsp; </TD>
<TD align=left><CODE>, - * /</CODE></TD></TR>
<TR>
<TD align=left><CODE>小时</CODE></TD>
<TD align=left>&nbsp; </TD>
<TD align=left><CODE>0-23</CODE></TD>
<TD align=left>&nbsp; </TD>
<TD align=left><CODE>, - * /</CODE></TD></TR>
<TR>
<TD align=left><CODE>日期</CODE></TD>
<TD align=left>&nbsp; </TD>
<TD align=left><CODE>1-31</CODE></TD>
<TD align=left>&nbsp; </TD>
<TD align=left><CODE>, - * ? / L W C</CODE></TD></TR>
<TR>
<TD align=left><CODE>月份</CODE></TD>
<TD align=left>&nbsp; </TD>
<TD align=left><CODE>1-12&nbsp;或者 JAN-DEC</CODE></TD>
<TD align=left>&nbsp; </TD>
<TD align=left><CODE>, - * /</CODE></TD></TR>
<TR>
<TD align=left><CODE>星期</CODE></TD>
<TD align=left>&nbsp; </TD>
<TD align=left><CODE>1-7&nbsp;或者 SUN-SAT</CODE></TD>
<TD align=left>&nbsp; </TD>
<TD align=left><CODE>, - * ? / L C #</CODE></TD></TR>
<TR>
<TD align=left><CODE>年（可选）</CODE></TD>
<TD align=left>&nbsp; </TD>
<TD align=left><CODE>留空, 1970-2099</CODE></TD>
<TD align=left>&nbsp; </TD>
<TD align=left><CODE>, - * /</CODE></TD></TR></TBODY></TABLE></P><img src ="http://www.blogjava.net/javaora/aggbug/8070.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaora/" target="_blank">java世界畅谈</a> 2005-07-20 21:37 <a href="http://www.blogjava.net/javaora/archive/2005/07/20/8070.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>TriggerListeners and JobListeners</title><link>http://www.blogjava.net/javaora/archive/2005/07/20/8069.html</link><dc:creator>java世界畅谈</dc:creator><author>java世界畅谈</author><pubDate>Wed, 20 Jul 2005 13:27:00 GMT</pubDate><guid>http://www.blogjava.net/javaora/archive/2005/07/20/8069.html</guid><wfw:comment>http://www.blogjava.net/javaora/comments/8069.html</wfw:comment><comments>http://www.blogjava.net/javaora/archive/2005/07/20/8069.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaora/comments/commentRss/8069.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaora/services/trackbacks/8069.html</trackback:ping><description><![CDATA[<P>TriggerListeners and JobListeners<BR>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.</P>
<P>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).</P>
<P>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.&nbsp; 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.</P>
<P>&nbsp;scheduler.addGlobalJobListener(myJobListener);<BR>or<BR>&nbsp;scheudler.addJobListener(myJobListener);<BR>&nbsp;<BR>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.<BR></P><img src ="http://www.blogjava.net/javaora/aggbug/8069.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaora/" target="_blank">java世界畅谈</a> 2005-07-20 21:27 <a href="http://www.blogjava.net/javaora/archive/2005/07/20/8069.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>更多关于CronTrigger</title><link>http://www.blogjava.net/javaora/archive/2005/07/20/8046.html</link><dc:creator>java世界畅谈</dc:creator><author>java世界畅谈</author><pubDate>Wed, 20 Jul 2005 07:25:00 GMT</pubDate><guid>http://www.blogjava.net/javaora/archive/2005/07/20/8046.html</guid><wfw:comment>http://www.blogjava.net/javaora/comments/8046.html</wfw:comment><comments>http://www.blogjava.net/javaora/archive/2005/07/20/8046.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaora/comments/commentRss/8046.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaora/services/trackbacks/8046.html</trackback:ping><description><![CDATA[<P>More About CronTrigger<BR>更多关于CronTrigger</P>
<P>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.<BR>CronTriggers 比SimpleTrigger经常更加有用,如果你需要一个基于像日历概念的重复 job-firing 调度，而不是在一个SimpleTrigger特定的间隔。</P>
<P>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".<BR>使用CronTrigger,你可以限定firing-schedulers例如 “每天中午“，或者”，”每天周日上午9:30“，或者甚至 “每5分钟在上午9：00 到 10：00 每周一、周三、周五”</P>
<P>Cron Expressions<BR>Cron 表达式</P>
<P>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: <BR>Cron 表达式被用来注册CronTrigger实例的。Cron表达式是字符串，它由六个子表达式组成，它描述了不同的调度细节。这些子表达式被白色表达式隔开，表现：</P>
<P>Seconds&nbsp; 秒<BR>Minutes&nbsp; 分<BR>Hours&nbsp;&nbsp;&nbsp; 时<BR>Day-of-Month&nbsp; 日<BR>Month&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 月<BR>Day-of-Week&nbsp;&nbsp; 周</P>
<P>An example of a complete cron-expression is the string "0 0 12 ? * WED" - which means "every Wednesday at 12:00 pm".<BR>一个完整的Cron 表达式例子是字符串“0 0 12 ? * WEB” 意味着每周三上午12：00。</P>
<P>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".<BR>单独的子表达式可以包含平行的 和/或。例如，在上一个例子一周的一天字段（它读作"WED"）可以被“MON-FRI”,"MON,WED,FRI"，或者甚至"MON-WED,SAT"替换掉。</P>
<P>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".<BR>统配符（"*"字符）可以被用来作为这个字段的"每一个"可能值。所以,在上一个例子月字段中的"*"字符表示每个月。 一个"*"在周天将明显意味着周的每一天。</P>
<P>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.<BR>所有字段都用一个合法限定的值。这些值应该是明显的，例如0到59数字为秒和分的限定，0到23为小时。月的某天可以是0-31的，或者你需要消息给个月有多少天！月份可以被限定在0到11，或者，使用英文字符串缩写。一个礼拜的一天可以被限定作为1到7（1=Sunnday）或者使用英文字符串。</P>
<P><BR>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.<BR>"/"字符可以内用来限定值的增加。例如，如果你将'0/15'放到分钟字段，它意味着"每15分钟，开始于0分钟"。如果你使用"3/20"在分钟字段中，你将意味着"一个小时内每20分钟，开始于3分钟"---&nbsp; 或者换言之，它和在分钟字段"3,23,43"限定是一样的。</P>
<P><BR>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.</P>
<P>"?"字符是允许为月的某一天或者周的某一天字段的。它被用来限定"没有限定值"。这是有用的，当你需要限定一些事情在一个或两个字段中，但不是这里的。</P>
<P>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.</P>
<P>"L"字符是允许用来月某天和周某天字段。这个字符是一个"last"的缩写，但是它有不同的意义在两个字段的其中之一。例如，这个值"L"在月字段的某一天意味着" 这个月的最后一天"，31或者28等等。</P>
<P>Here are a few more examples of expressions and their meanings - you can find even more in the JavaDOC for CronTrigger</P>
<P>CronTrigger Example 1 - an expression to create a trigger that simply fires every 5 minutes</P>
<P>&nbsp; "0 0/5 * * * ?"</P>
<P>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.).</P>
<P>&nbsp; "10 0/5 * * * ?"</P>
<P>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.</P>
<P>&nbsp; "0 30 10-13 ? * WED,FRI"</P>
<P>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</P>
<P>&nbsp; "0 0/30 8-9 5,20 * ?"</P>
<P>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.</P><img src ="http://www.blogjava.net/javaora/aggbug/8046.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaora/" target="_blank">java世界畅谈</a> 2005-07-20 15:25 <a href="http://www.blogjava.net/javaora/archive/2005/07/20/8046.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>What is Quartz? (什么是Quartz?)</title><link>http://www.blogjava.net/javaora/archive/2005/07/20/8036.html</link><dc:creator>java世界畅谈</dc:creator><author>java世界畅谈</author><pubDate>Wed, 20 Jul 2005 04:05:00 GMT</pubDate><guid>http://www.blogjava.net/javaora/archive/2005/07/20/8036.html</guid><wfw:comment>http://www.blogjava.net/javaora/comments/8036.html</wfw:comment><comments>http://www.blogjava.net/javaora/archive/2005/07/20/8036.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/javaora/comments/commentRss/8036.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaora/services/trackbacks/8036.html</trackback:ping><description><![CDATA[<P>What is Quartz? (什么是Quartz?)<BR>Quartz is a full-featured, open source job scheduling system that can be integrated with, or used along side virtually any J2EE or J2SE application - from the smallest stand-alone application to the largest e-commerce system. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks are defined as standard Java components or EJBs. The Quartz Scheduler includes many enterprise-class features, such as JTA transactions and clustering.</P>
<P>Quartz 是一个功能齐全的、开源的job时间调度系统，它可以被结合的,或者伴随虚拟的任何J2EE或J2SE程序-从最小的独立的应用程序到最大的e-commerce系统被使用。Quartz可以用来创建简单或复杂的时间调度来执行十、百、千、甚至上万的jobs;获得的job被定义为一个标准的java组件或EJBs. 这个Quartz 时间调度包含很多企业类的特征，例如JTA事务和簇。</P>
<P>The licensing of Quartz versions 1.0 through 1.4.5 is similar to both the BSD and ASF (Apache) public licenses, which means it's free for use, even within commercial products.</P>
<P>Quartz 1.0版本到1.4.5版本的licensing 是类似与BSD和ASF(apache)公共licenses, 它意味着可以免费使用，甚至使用在商业产品中使用。<BR>With the upcoming release of version 1.5.0, Quartz is moving to the Apache 2.0 license.<BR>伴随1.5.0版本的发布，Quartz将转移向apache 2.0 的license.</P>
<P>What can Quartz do for you? (Quartz可以为你做什么？)<BR>If your application has tasks that need to occur at given moments in time, or if your system has recurring maintenance jobs then Quartz may be your ideal solution.</P>
<P>如果你的程序有一些这样的任务，它需要及时地发生在给定时间，或者你如果你的系统有连续维护jobs，那么Quartz可以成为你的理想的解决方案。</P>
<P>Sample uses of job scheduling with Quartz:<BR>Quartz使用job时间调度的范例</P>
<P>Driving Workflow: As a new order is initially placed, schedule a Job to fire in exactly 2 hours, that will check the status of that order, and trigger a warning notification if an order confirmation message has not yet been received for the order, as well as changing the order's status to 'awaiting intervention'. <BR>System Maintenance: Schedule a job to dump the contents of a database into an XML file every business day (all weekdays except holidays) at 11:30 PM. </P>
<P>工作流驱动：作为一个新的订单被初始化放置，调度一个job去工作在正好两个小时内，它将检查订单的状态，并且触发一个警告通知如果订单确认信息没有被接收，又改变订单的状态到"等待干涉"。<BR>系统维护：调度一个job来将数据库转化为XML文件 每商业日期（所有周末除了节假日）在下午11：30。</P>
<P>&nbsp;</P><img src ="http://www.blogjava.net/javaora/aggbug/8036.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaora/" target="_blank">java世界畅谈</a> 2005-07-20 12:05 <a href="http://www.blogjava.net/javaora/archive/2005/07/20/8036.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Using the ProxyFactoryBean to create AOP proxies</title><link>http://www.blogjava.net/javaora/archive/2005/07/07/7249.html</link><dc:creator>java世界畅谈</dc:creator><author>java世界畅谈</author><pubDate>Thu, 07 Jul 2005 02:43:00 GMT</pubDate><guid>http://www.blogjava.net/javaora/archive/2005/07/07/7249.html</guid><wfw:comment>http://www.blogjava.net/javaora/comments/7249.html</wfw:comment><comments>http://www.blogjava.net/javaora/archive/2005/07/07/7249.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaora/comments/commentRss/7249.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaora/services/trackbacks/7249.html</trackback:ping><description><![CDATA[<P>Using the ProxyFactoryBean to create AOP proxies<BR>If you're using the Spring Ioc container (an applicationContext or BeanFactory) for you business object--and you should be!-- you will want to use one of Spring's AOP fatoryBeans.(Remeber that a factory bean introduces a layer of indirection, enabling it to create objects of different type).</P>
<P>The basic way to create an AOP proxy in Spring to use the org.springframework.aop.framework.ProxyFactoryBean. This gives complete control over the pointcuts an advice that will apply, and theire ordering . However ,there are simpler options that are preferable(更可取的、更好的) if you don't need such control.</P>
<P>Basics<BR>The proxyFactoryBean,like other Spring FactoryBean implementations,introduces a level of indirection(间接). If you define a ProxyFactoryBean with name foo,what objects referencing foo see is not the ProxyFactoryBean instance itself, but an object created by the ProxyFactoryBeans's implementation of the getObject() method. This method will create an AOP proxy wrapping a target object.</P>
<P>One of the most important benefits of using a ProxyFactoryBean or other IoC-aware to create AOP proxies, it that it means that advices and pointcuts can also be managed by IoC. This is a powerful feature , enabling certain approaches that are hard to achieve with other AOP frameworks. For example,an advice may itself reference application objects(besides the target , which should be available in any AOP framework),benefiting from all the pluggability provided by Dependency Injection.</P>
<P>JavaBean properties<BR>Like most FactoryBean implementations provided with Spring, ProxyfactoryBean is itself a JavaBean. It properties are used to:<BR>Specify the target you&nbsp; want to proxy<BR>Specify whether to use CGLIB</P>
<P>Some key properties are inherited from org.springframework.aop.framework.ProxyConfig: the subclass for all AOP proxy factories. These include:<BR>proxyTargetClass: true if we should proxy the target class,rather than its interfaces. If this&nbsp; is true we need to use CGLIB.</P>
<P>optimize: whether to apply aggressive optimization to created proxies. Don't use this setting unless you&nbsp; understand how the relevant(相关的) AOP proxy handles optimization. This is currently used only for CGLIB proxies;it has no effect with&nbsp; JDK dynamic proxies(the default).</P>
<P>frozen:whether avice changes should be disallowed once the proxy factory has bean configured. Default is false.</P>
<P>exposeProxy: whether the current proxy should be exposed in a ThreadLocal so that it can be accessed by the target (It's available via the MethodInvocation without the need for a ThreadLocal) If a target needs to obtain the proxy and exposedProxy is true, the target can use the AopContext.currentProxy() method.</P>
<P>aopProxyFactory: the implementation of AopProxyFactory to use. Offers a way of customizing whether to use dynammic proxies,CGLIB or any other proxy strategy. The default implementation will choose dynamic proxies or CGLIB appropriately. There should be need to use this property, it's intended to allow the addition of new proxy types in spring 1.1.</P>
<P>Other properties specific to ProxyFactoryBean include:<BR>.proxyInterfaces: array of String interface names.&nbsp; If this isn't supplied, a CGLIB proxy for the target class will be used.<BR>.interceptorNames:String array of Advisor,interceptor or other advice names to apply.Ordering is sugnicicant. first come,first serve that is. The first interceptor in the list will be the first to be able to interceptor the invocation (of course if it concerns a regular MethodInterceptor or BeforeAdvice. The names are bean names in the current factory , including&nbsp; bean names from ancestor factories. You&nbsp; can't mention bean references here since doing so would result iin the ProxyFactoryBean ignoring the singleton&nbsp; setting of the advise. you can append an iinterceptor name with an asterisk(*).&nbsp; This will result&nbsp; in the application of all advisor beans withe names starting with the part before the asterisk to be applied.&nbsp; An example of using this feature can be found below.</P>
<P>Singleton: whether or not the factory should return a single object, no matter how often the getObject() method is called. Server FactoryBean implementations offer such a method. Default value is true. If you want to use stateful advice --for example ,for stateful mixins-user prototype advices along withe s singleton value of false.</P>
<P>Proxying interfaces</P>
<P>&lt;bean id="personTarget" class="com.mycompany.PersionImpl"&gt;<BR>&nbsp;&nbsp; &lt;property name="name"&gt;&lt;value&gt;Tony&lt;/value&gt;&lt;/property&gt;<BR>&nbsp;&nbsp; &lt;property name="age"&gt;&lt;value&gt;51&lt;/value&gt;&lt;/property&gt;&nbsp;&nbsp; <BR>&lt;/bean&gt;</P>
<P>&lt;bean id="myAdvisor" class="com.mycompany.MyAdvisor"&gt;<BR>&nbsp;&nbsp; &lt;property name="someProperty"&gt;&lt;value&gt;Custom string property value&lt;/value&gt;&lt;/property&gt;<BR>&lt;/bean&gt;</P>
<P>&lt;bean id="debugInterceptor" class="org.springframework.aop.interceptor.DebugInteceptor" &gt;&lt;/bean&gt;</P>
<P>&lt;bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean"&gt;<BR>&nbsp;&nbsp; &lt;property name="proxyInterface"&gt;&lt;value&gt;com.company.Person&lt;/value&gt;&lt;/property&gt;<BR>&nbsp;&nbsp; <BR>&nbsp;&nbsp; &lt;property name="target"&gt;&lt;ref local="personTarget"/&gt;&lt;/property&gt;<BR>&nbsp;&nbsp; &lt;property name="interceptorNames"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;list&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;myAdvisor&lt;/value&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;debugInterceptor&lt;/value&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/list&gt;<BR>&nbsp;&nbsp; &lt;/property&gt;<BR>&lt;/bean&gt;</P>
<P>&nbsp;</P><img src ="http://www.blogjava.net/javaora/aggbug/7249.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaora/" target="_blank">java世界畅谈</a> 2005-07-07 10:43 <a href="http://www.blogjava.net/javaora/archive/2005/07/07/7249.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring中的 JasperReports</title><link>http://www.blogjava.net/javaora/archive/2005/06/29/6863.html</link><dc:creator>java世界畅谈</dc:creator><author>java世界畅谈</author><pubDate>Wed, 29 Jun 2005 02:24:00 GMT</pubDate><guid>http://www.blogjava.net/javaora/archive/2005/06/29/6863.html</guid><wfw:comment>http://www.blogjava.net/javaora/comments/6863.html</wfw:comment><comments>http://www.blogjava.net/javaora/archive/2005/06/29/6863.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaora/comments/commentRss/6863.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaora/services/trackbacks/6863.html</trackback:ping><description><![CDATA[<P>13.7. JasperReports<BR>JasperReports (<A href="http://jasperreports.sourceforge.net">http://jasperreports.sourceforge.net</A>) is a powerful, open-source reporting engine that supports the creation of report designs using an easily understood XML file formats. JasperReports is capable of rendering reports output into four different formats: CSV, Excel, HTML and PDF.</P>
<P>13.7.1. Dependencies （依赖）<BR>Your application will need to include the latest release of JasperReports, which at the time of writing was 0.6.1. JasperReports itself depends on the following projects:</P>
<P>BeanShell</P>
<P>Commons BeanUtils</P>
<P>Commons Collections</P>
<P>Commons Digester</P>
<P>Commons Logging</P>
<P>iText</P>
<P>POI</P>
<P>JasperReports also requires a JAXP compliant(适应的) XML parser.</P>
<P>13.7.2. Configuration（配置）<BR>To configure JasperReports views in your ApplicationContext you have to define a ViewResolver to map view names to the appropriate view class depending on which format you want your report rendered in.</P>
<P>13.7.2.1. Configuring the ViewResolver<BR>Typically, you will use the ResourceBundleViewResolver to map view names to view classes and files in a properties file </P>
<P>&lt;bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver"&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;property name="basename"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;views&lt;/value&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/property&gt;<BR>&lt;/bean&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>Here we've configured an instance of ResourceBundleViewResolver which will look for view mappings in the resource bundle with base name views. The exact contents of this file is described in the next section.</P>
<P>13.7.2.2. Configuring the Views<BR>Spring contains five different View implementations for JasperReports four of which corresponds to one of the four output formats supported by JasperReports and one that allows for the format to be determined at runtime:</P>
<P>JasperReport View Class<BR>1.JasperReportsView&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CSV<BR>2.JasperReportsHtmlView&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HTML<BR>3.JasperReportsPdfView&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PDF<BR>4.JasperReportsXlsView&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EXCEL<BR>5.JasperReportsMutiFormatView </P>
<P>Mapping one of these classes to a view name and a report file is simply a matter of adding the appropriate entries into the resource bundle configured in the previous section as shown here:</P>
<P>simpleReport.class=org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView<BR>simpleReport.url=/WEB-INF/reports/DataSourceReport.jasper<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>Here you can see that the view with name, simpleReport, is mapped to the JasperReportsPdfView class. This will cause the output of this report to be rendered in PDF format. The url property of the view is set to the location of the underlying report file.</P>
<P><BR>13.7.2.3. About Report Files<BR>JasperReports has two distinct types of report file: the design file, which has a .jrxml extension, and the compiled report file, which has a .jasper extension. Typically, you use the JasperReports Ant task to compile your .jrxml design file into a .jasper file before deploying it into your application. With Spring you can map either of these files to your report file and Spring will take care of compiling the .jrxml file on the fly for you. You should note that after a .jrxml file is compiled by Spring, the compiled report is cached for the life of the application. To make changes to the file you will need to restart your application.</P>
<P>JasperReports拥有两种不同的类型的报表文件：设计文件，它是一个拥有.jrxml 扩展的文件，和编译好的报表文件。一般，你使用ant任务在你部署到你的程序中之前来编译你的.jrxml设计报表文件。使用Spring 你可以影射这些文件中的任一到你的报表文件，Spring将会为你在空闲时照顾编译.jrxml文件。 你应当注意在一个.jrxml文件被编译之后，这个编译的报表是被缓存的在你的application生命周期中。如果这些文件修改了，你需要重新启动的你的程序。</P>
<P>13.7.2.4. Using JasperReportsMultiFormatView&nbsp; 使用JasperReportsMutiFormatView<BR>The JasperReportsMultiFormatView allows for report format to be specified at runtime. The actual rendering of the report is delegated to one of the other JasperReports view classes - the JasperReportsMultiFormatView class simply adds a wrapper layer that allows for the exact implementation to be specified at runtime.</P>
<P>JasperReportsMutilFormatView允许你在运行时期指定报表的格式。报表的实际的表现是为委托到JasperReports 视图类的中的一个--JasperMutilFormatView类简单的加了一个包装层允许在运行时期正确的实现被指定。</P>
<P>The JasperReportsMultiFormatView class introduces two concepts: the format key and the discriminator key. The JasperReportsMultiFormatView class uses the mapping key to lookup the actual view implementation class and uses the format key to lookup up the mapping key. From a coding perspective you add an entry to your model with the formay key as the key and the mapping key as the value, for example:</P>
<P>&nbsp;</P>
<P>public ModelAndView handleSimpleReportMulti(HttpServletRequest request,<BR>HttpServletResponse response) throws Exception {</P>
<P>&nbsp; String uri = request.getRequestURI();<BR>&nbsp; String format = uri.substring(uri.lastIndexOf(".") + 1);</P>
<P>&nbsp; Map model = getModel();<BR>&nbsp; model.put("format", format);</P>
<P>&nbsp; return new ModelAndView("simpleReportMulti", model);<BR>}<BR>In this example, the mapping key is determined from the extension of the request URI and is added to the model under the default format key: format. If you wish to use a different format key then you can configure this using the formatKey property of the JasperReportsMultiFormatView class.</P>
<P>By default the following mapping key mappings are configured in JasperReportsMultiFormatView: <BR>Table 13.3. JasperReportsMultiFormatView Default Mapping Key Mappings</P>
<P>Mapping Key View Class <BR>csv&nbsp;&nbsp; JasperReportsCsvView <BR>html&nbsp; JasperReportsHtmlView <BR>pdf&nbsp;&nbsp; JasperReportsPdfView <BR>xls&nbsp;&nbsp; JasperReportsXlsView </P>
<P>So in the example above a request to URI /foo/myReport.pdf would be mapped to the JasperReportsPdfView class. You can override the mapping key to view class mappings using the formatMappings property of JasperReportsMultiFormatView.</P><img src ="http://www.blogjava.net/javaora/aggbug/6863.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaora/" target="_blank">java世界畅谈</a> 2005-06-29 10:24 <a href="http://www.blogjava.net/javaora/archive/2005/06/29/6863.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Remoting using Spring</title><link>http://www.blogjava.net/javaora/archive/2005/06/24/6656.html</link><dc:creator>java世界畅谈</dc:creator><author>java世界畅谈</author><pubDate>Fri, 24 Jun 2005 02:15:00 GMT</pubDate><guid>http://www.blogjava.net/javaora/archive/2005/06/24/6656.html</guid><wfw:comment>http://www.blogjava.net/javaora/comments/6656.html</wfw:comment><comments>http://www.blogjava.net/javaora/archive/2005/06/24/6656.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/javaora/comments/commentRss/6656.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/javaora/services/trackbacks/6656.html</trackback:ping><description><![CDATA[<P>Considerations when choosing a technology （当选择一个技术时候的考虑）<BR>Each and every technology presented here has its drawbacks. You should carefully consider you needs, the services your exposing and the objects you'll be sending over the wire when choosing a technology. <BR>每个技术这里介绍的都有它的缺点。你应该仔细考虑你的需要，当你选择的时考虑你的暴露的服务和你将要发送关系的对象。</P>
<P><BR>When using RMI, it's not possible to access the objects through the HTTP protocol, unless you're tunneling the RMI traffic. RMI is a fairly heavy-weight protocol in that it support full-object serialization which is important when using a complex data model that needs serialization over the wire. However, RMI-JRMP is tied to Java clients: It is a Java-to-Java remoting solution. <BR>当我们使用RMI，我们不可以通过http协议访问对象，除非你打通RMI交通的隧道。RMI 是一个非常重量级协议，在其中他支持的所有对象的序列化是非常重要的，当使用一个需要序列化关联的复杂的数据模型。然而，RMI-JRMP 是依赖java客户端的：它是java-to-java的远程解决方案。</P>
<P><BR>Spring's HTTP invoker is a good choice if you need HTTP-based remoting but also rely on Java serialization. It shares the basic infrastructure with RMI invokers, just using HTTP as transport. Note that HTTP invokers are not only limited to Java-to-Java remoting but also to Spring on both the client and server side. (The latter also applies to Spring's RMI invoker for non-RMI interfaces.) <BR>Spring 的HTTP invoker 是一个不错的选择，如果你需要基于HTTP的远程，而且需要java序列化回复。它使用RMI invoker分享了基础结构，仅仅使用HTTP作为传输。注意HTTP invoker不是仅仅限制给java-to-java的远程而且是在客户端和服务器端的Spring.(后面的也应用到Spring 的RMI invoker为非RMI的接口)。</P>
<P>Hessian and/or Burlap might provide significant value when operating in a heterogeneous environment, because they explicitly allow for non-Java clients. However, non-Java support is still limited. Known problems include the serialization of Hibernate objects in combination with lazily initializing collections. If you have such a data model, consider using RMI or HTTP invokers instead of Hessian. <BR>Hessian 和或 Burlap可以支持重要的值，当在一个异质的环境操作，因为他们明确的允许为非java 对象。然而非java对象是受限制的，知道的问题包括hibernate对象序列化与懒汉初始化集合的结合上。如果你有这样的数据模型，考虑使用RMI或HTTP invokers而不是Hessioan.</P>
<P>JMS can be useful for providing clusters of services and allowing the JMS broker to take care of load balancing, discovery and auto-failover. By default Java serialization is used when using JMS remoting but the JMS provider could use a different mechanism for the wire formatting, such as XStream to allow servers to be implemented in other technologies. </P>
<P><BR>Last but not least, EJB has an advantage over RMI in that it supports standard role-based authentication and authorization and remote transaction propagation. It is possible to get RMI invokers or HTTP invokers to support security context propagation as well, although this is not provided by core Spring: There are just appropriate hooks for plugging in third-party or custom solutions here. </P>
<P>&nbsp;</P><img src ="http://www.blogjava.net/javaora/aggbug/6656.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/javaora/" target="_blank">java世界畅谈</a> 2005-06-24 10:15 <a href="http://www.blogjava.net/javaora/archive/2005/06/24/6656.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>