第32章 Spring框架对J2EE服务的集成之扩展篇

第32章 Spring框架对J2EE服务的集成之扩展篇

本章内容

  • MailMonitor的延伸

  • Spring 3.0展望

32.1 MailMonitor的延伸

你或许会纳闷?什么是MailMonitor?从它能够延伸出什么?下面让我们一起来揭开这个谜底。

MailMonitor是我曾经参与的信贷项目(CREDIT)中的一个批处理程序。该批处理程序将检查CREDIT系统向顾客发送的各类邮件是否发送成功,如果发现邮件标题中含有发送失败的信息关键字,则对这些错误邮件进行接收并分析,将分析后的信息存入各种数据表,然后再将处理后的邮件删除。可以说整个MailMonitor批处理的需求和实现都很简单。之所以它拿开刀,是因为它的应用需求并不难理解,而且,“麻雀虽小,五脏俱全”。对MailMonitor的剖析和重构,可以让我们从整体上回顾一下Spring对各种JavaEE服务的集成支持。

俗话讲,“家丑不可外扬”。不过,如果能够从过去吸取教训并进步,也不算坏事,所以,我就把04年的代码晾晒于下然后让我们一起对其进行一番批斗,如何?

public class MailMonitorJob extends QuartzJobBean {
    
    
  private static final Logger logger = Logger.getLogger(MailMonitorJob.class);
  
	private ServletAuthUtils authUtils;
	private List keyWord;
  
	private IMonitorRequestProcessor requestProcessor;
  
	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
    
    
		Store store = null;
		Folder f = null;
		try {
    
    
			Properties prop = System.getProperties();
			Session session = Session.getDefaultInstance(prop, null);
	
      ServletAuthResult result = authUtils.auth();
			String host = result.getSmtpServer();
			String user = result.getSmtpUser();
			String password = result.getSmtpPassword();
	
      URLName url = newURLName("pop3", host, -1, "INBOX", user, password);
      
			store = session.getStore(url);
			store.connect(host, user, password);
	
      f = store.getFolder("INBOX");
			if(f==null || !f.exists()) {
    
    
				return;
      }
			f.open(Folder.READ_WRITE);
			if(!f.isOpen()) {
    
    
				return;
      }
			
      Message[] messages = f.getMessages();
			if(ArrayUtils.isEmpty(messages)) {
    
    
				if(logger.isInfoEnabled()) {
    
    
					logger.info("NoMessageExistsinthemail-list!");
        }
				return;
      }
      processFailureMessages(messages);
    }
		catch(Exception e) {
    
    
			throw new JobExecutionException(e);
    }
		finally {
    
    
			closeFolder(f);
			closeStore(store);
    }
  }
	// 其他helper方法定义
}

在审视这段代码的时候,我们可以发现以下这些问题或者需要改进的地方,甚至更多,如下所述。

  • 我们让批处理任务实现类直接继承了Spring的QuartzJobBean。在介绍Spring对Quartz的集成的时候,我们提到,虽然QuartzJobBean可以让我们的批处理任务实现类获得配置的好处,但其极强的侵入性使得它的存在已经不合时宜。显然,让我们的MailMonitorJob脱离QuartzJobBean是我们重构所需要做的第一个工作。

  • 邮件接收和邮件处理相关功能关注点没有进行合理的分离,JavaMailAPI的使用代码与邮件处理相关代码相互纠缠,这使得整段代码的重用性和可扩展性极差。为了改善这种状况,我们可能需要做如下工作。

    • 剥离使用JavaMail API实现的邮件接收功能到独立的Helper类,使得该Helper类可以提供可重用的邮件接收基础设施代码。Spring提供了MailSender和JavaMailSender等基础设施用于邮件的发送,可并没有提供对邮件接收功能的集成设施,我们的Helper就是要完成这一功能。而至于如何来实现这个用于邮件接收的Helper类,参照之前Spring给予我们的经验或者JavaMailSender的实现,我想你心中早就有数了。虽然邮件信息接收后的解析和处理不好统一,但是API相关的资源管理等都可以模板化。至于最终实现,我就不再哆嗦了。

    • 最初的MailMonitor实现,是将发送失败的邮件信息的处理逻辑,整个放在了MailMonitorJob内实现,而且处理邮件信息的方式也只是简单的循环依次处理,如下所示:

      Message[] messages = ...; // 我们接收到的message
      for(Message message : messages) {
        // 解析message
        // 持久化存储解析后的message信息
        // 从邮件服务器删除该message
      }
      

对这种情况的重构,我们可以引入TaskExecutor来解耦任务的提交和执行,这不但可以将邮件处理逻辑以任务(Task)的形式进行合适粒度的封装,而且还可以引入灵活的任务处理策略,何乐而不为呢?

如果我们能够从这几个方面对最初的MailMonitor进行重构,我们基本就完成了从Spring的MailSender抽象层到任务调度和TaskExecutor的基本回顾,牵强一点儿,再让JavaMail的Session从JNDI获取,那么也就剩下JMS没有顾及到了。但是我想,如果我们能够从MailMonitor这只“麻雀”的剖析中引申出去的话,是不是可以发现更加广阔的天地呢?实际上,这也正是我所希望的!

32.2 Spring 3.0展望

Java5中,JSR 166(Concurrency Utilities)的引入,对于Java平台来说可谓意义深重。Spring 3.0中将继续倾注更多热情在对并发的支持上面,这包括:

  • 更新TaskExecutor抽象接口,以便更好地与现有的ava.util.concurrent进行集成;

  • 为Callable和Future提供一等公民待遇,为ExecutorService和ThreadFactory提供相应的集成支持,以便它们能够更好的融入Spring容器的怀抱;

  • 提供异步方法调用支持,这可以通过Spring 3.0新添加的@Async或者EJB3.1中的@Asynchronous进行触发。

除此之外,Spring 3.0中还可能为任务调度(scheduling)提供独立的命名空间(name space),这将大大简化相应的配置。最后要提到的就是,Spring 3.0中会提供使用cron表达式的Timer。至于长什么样子,我们只能“走着瞧”了。

32.3 小结

本章主要想就着对MailMonitor的剖析和重构,帮助你进一步巩固本部分Spring对各种JavaEE服务的集成相关内容。

猜你喜欢

转载自blog.csdn.net/qq_34626094/article/details/125956949