7.4. simple-weather模块

我们将要检查的下一个模块可以被认为是一个“服务”。这个simple-weather模块包含了所有从Yahoo! Weather RSS数据源获取数据并解析的必要逻辑。虽然simple-weather只包含了三个Java类和一个JUnit测试,它还将展现为一个单独的组件,WeatherService,同时为简单web应用和简单命令行工具服务。通常来说一个企业级项目会包含一些API模块,这写模块包含了重要的业务逻辑,或者与外部系统交互的逻辑。一个银行系统可能有一个模块,从第三方数据提供者获取并解析数据,而一个显示赛事比分的系统可能会与一个提供实时篮球或足球比分的XML数据源进行交互。在Example 7.5, “simple-weather 模块的 POM”中,该模块封装了所有的网络活动,以及与Yahoo! Weather交互涉及的XML解析活动。其它依赖于该模块的项目只要简单的调用WeatherServiceretrieveForecast()方法,该方法接受一个邮政编码作为参数,返回一个Weather对象。

Example 7.5. simple-weather 模块的 POM

<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                      http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.sonatype.mavenbook.ch07</groupId>
    <artifactId>simple-parent</artifactId>
    <version>1.0</version>
  </parent>
  <artifactId>simple-weather</artifactId>
  <packaging>jar</packaging>

  <name>Simple Weather API</name>

  <dependencies>
    <dependency>
      <groupId>org.sonatype.mavenbook.ch07</groupId>
      <artifactId>simple-model</artifactId>
      <version>1.0</version>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.14</version>
    </dependency>
    <dependency>
      <groupId>dom4j</groupId>
      <artifactId>dom4j</artifactId>
      <version>1.6.1</version>
    </dependency>
    <dependency>
      <groupId>jaxen</groupId>
      <artifactId>jaxen</artifactId>
      <version>1.1.1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-io</artifactId>
      <version>1.3.2</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>


这个simple-weather POM扩展了simple-parent POM,设置打包方式为jar,然后添加了下列的依赖:

org.sonatype.mavenbook.ch07:simple-model:1.0

simple-weather将Yahoo! Weather RSS数据源解析成一个Weather对象。 它有一个对simple-model的直接依赖。.

log4j:log4j:1.2.14

simple-weather使用Log4J类库来打印日志信息。

dom4j:dom4j:1.6.1 and jaxen:jaxen:1.1.1

这两个依赖都用来解析从Yahoo! Weather返回的XML

org.apache.commons:commons-io:1.3.2 (scope=test)

这个test范围的依赖是由YahooParserTest使用的。

接下来是WeatherService类,在Example 7.6, “WeatherService 类”中显示。这个类和Example 6.3, “WeatherService 类”中的WeatherService类看起来很像。虽然WeatherService名字一样,但与本章中的样例还是有细微的差别。这个版本的retrieveForecast()方法返回一个Weather对象,而格式就留给调用WeatherService的程序去处理。其它的主要变化是,YahooRetrieverYahooParser都是WeatherService bean的bean属性。

Example 7.6. WeatherService 类

package org.sonatype.mavenbook.weather;

import java.io.InputStream;

import org.sonatype.mavenbook.weather.model.Weather;

public class WeatherService {

  private YahooRetriever yahooRetriever;
  private YahooParser yahooParser;

  public WeatherService() {}

  public Weather retrieveForecast(String zip) throws Exception {
    // Retrieve Data
    InputStream dataIn = yahooRetriever.retrieve(zip);

    // Parse DataS
    Weather weather = yahooParser.parse(zip, dataIn);

    return weather;
  }

  public YahooRetriever getYahooRetriever() {
    return yahooRetriever;
  }

  public void setYahooRetriever(YahooRetriever yahooRetriever) {
    this.yahooRetriever = yahooRetriever;
  }

  public YahooParser getYahooParser() {
    return yahooParser;
  }

  public void setYahooParser(YahooParser yahooParser) {
    this.yahooParser = yahooParser;
  }
}

最后,在这个项目中我们有一个由Spring Framework用来创建ApplicationContextXML文件。首先,一些解释:两个应用程序,web应用和命令行工具,都需要和WeatherService类交互,而且它们都使用名字weatherService从Spring ApplicationContext获取此类的一个实例。我们的web应用使用一个与WeatherService实例关联的Spring MVC控制器,我们的命令行应用在静态main()方法中从ApplicationContext载入这个WeatherService。为了鼓励重用,我们已经在src/main/resources中包含了一个applicationContext-weather.xml文件,这样便在classpath中可用。依赖于simple-weather模块的模块可以使用Spring Framework中的ClasspathXmlApplicationContext载入这个Application Context。之后它们就能引用名为weatherServiceWeatherService实例。

Example 7.7. simple-weather模块的Spring Application Context

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
             http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    default-lazy-init="true">

    <bean id="weatherService" 
             class="org.sonatype.mavenbook.weather.WeatherService">
      <property name="yahooRetriever" ref="yahooRetriever"/>
      <property name="yahooParser" ref="yahooParser"/>
    </bean>    

    <bean id="yahooRetriever" 
             class="org.sonatype.mavenbook.weather.YahooRetriever"/>    

    <bean id="yahooParser" 
             class="org.sonatype.mavenbook.weather.YahooParser"/>
</beans>

该文档定义了三个bean:yahooParseryahooRetriever,和weatherServiceweatherService bean是WeatherService的一个实例,这个XML文档通过引用对应类的命名实例来填充yahooParseryahooRetriever属性。可以将这个applicationContext-weather.xml文件看作是定义了这个多模块项目中一个子系统的架构。其它项目如simple-webappsimple-command可以引用这个上下文,获取一个已经建立好与YahooRetrieverYahooParser实例关系的WeatherService实例。