Maven 与 Spring 结合进行模块化开发实践
Contents
模块化的解决方案
OSGi
是一种模块化标准。是真正意义的上模块化,Eclipse 就是基于OSGi进行开发的。热插拔,每个模块都有自己的classLoader,不同classLoader之间,通过服务来进行通信。
Maven
使用maven的方式来进行模块化,主要是代码组织,以及代码重用度角度来进行模块化。
实践
emacsist-project
创建该项目,用于被继承,以及聚合各个模块。
它的pom.xml
内容如下:
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 总pom -->
<groupId>org.emacsist</groupId>
<artifactId>emacsist-project</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<name>emacsist-project</name>
<url>http://emacsist.github.io</url>
<properties>
<spring.version>3.2.14.RELEASE</spring.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<modules>
<!-- 工具类模块 -->
<module>../emacsist-kit</module>
<module>../emacsist-email</module>
<module>../emacsist-http</module>
<module>../emacsist-redis</module>
<!-- weibosdk -->
<module>../weibosdk-base</module>
<module>../weibosdk-redis</module>
<module>../weibosdk-dao</module>
<module>../weibosdk-rabbitmq</module>
<module>../weibosdk-service</module>
<module>../common-pojo</module>
<module>../weibosdk-web</module>
<module>../weibosdk-interceptor</module>
</modules>
<dependencyManagement>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
...为了本文的篇幅,以下依赖忽略
</dependencies>
</dependencyManagement>
</project>
dependencyManagement
元素,主要是用于模块之间的版本一致管理。
emacsist-dao 模块
pom.xml
内容如下:
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 属于 emacsist-project 的子模块,继承父模块 -->
<parent>
<groupId>org.emacsist</groupId>
<artifactId>emacsist-project</artifactId>
<version>1.0.0</version>
<relativePath>../emacsist-project/pom.xml</relativePath>
</parent>
<groupId>org.emacsist.weibosdk</groupId>
<artifactId>weibosdk-dao</artifactId>
<packaging>jar</packaging>
<name>weibosdk-dao</name>
<url>http://maven.apache.org</url>
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<!-- 开发环境的配置文件 -->
</properties>
</profile>
<profile>
<id>product</id>
<properties>
<!-- 生产环境的配置文件 -->
</properties>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<scriptSourceDirectory>${runtime.env}</scriptSourceDirectory>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>${runtime.env}</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.json</include>
<include>**/*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
代码组织未例:
src/main/env/dev
: 开发环境的配置文件
src/main/env/product
: 生产环境的配置文件
src/main/java/
: 主源码
src/test/java
: 测试源码
src/test/env/dev
: 测试环境的配置文件
配置文件里,包含如下文件:
mybatis-config.xml
:mybatis配置文件,放在dao这个模块。即各自的模块,负责配置各自的配置文件
weibosdk-jdbc.properties
:jdbc配置文件
weibosdk-module-dao.xml
: dao模块的spring的配置文件,只需要配置属于dao的内容即可.
示例:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<bean id="uniweibov2DataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxActive">
<value>64</value>
</property>
<property name="maxIdle">
<value>64</value>
</property>
<property name="maxWait">
<value>0</value>
</property>
<property name="validationQuery">
<value>select 1</value>
</property>
<property name="testWhileIdle">
<value>true</value>
</property>
<property name="minEvictableIdleTimeMillis">
<value>20000000</value>
</property>
<property name="timeBetweenEvictionRunsMillis">
<value>3600000</value>
</property>
</bean>
<bean id="TxManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="uniweibov2DataSource" />
</bean>
<tx:annotation-driven transaction-manager="TxManager"
proxy-target-class="true" />
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="uniweibov2DataSource" />
<property name="configLocation" value="classpath:mybatis-config.xml" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="org.emacsist.weibosdk.dao.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
</beans>
其他模块
其他模块,类似于上面的dao模块的 pom.xml
web模块
这个是主要的运行模块,依赖于其他子模块。主要解决的问题:聚合其他模块的配置文件以及bean这些东西。
集合其他模块的properties
文件:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:weibo4j.properties</value>
<value>classpath:weibosdk-core.properties</value>
<value>classpath*:weibosdk-redis.properties</value>
<value>classpath*:weibosdk-rabbitmq.properties</value>
<value>classpath*:weibosdk-jdbc.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
注意是classpath*:weibosdk-模块的.properties
集合其他模块的spring.xml
<import resource="classpath*:weibosdk-module-dao.xml" />
<import resource="classpath*:weibosdk-module-interceptor.xml" />
<import resource="classpath*:weibosdk-module-rabbitmq.xml" />
<import resource="classpath*:weibosdk-module-redis.xml" />
<import resource="classpath*:weibosdk-module-task.xml" />
注意,也是classpath*:weibosdk-module-模块的.xml
表示从jar
包里查找这些配置文件。因为其他模块,都被打包成了jar
包。
构建,测试,运行,打包
这个在 emacsist-project下执行
构建指定模块
mvn clean install[test,package] -pl 模块1,模块2
构建指定模块,以及这些模块所依赖的模块
mvn clean install[test,package] -pl 模块1,模块2 -am
构建依赖于指定模块以及该模块本身
mvn clean install[test,package] -pl 模块 -amd
指定从哪个模块开始构建
mvn clean install[test,package] -rf 模块名
成功的话,输出类似:
[INFO]
[INFO] emacsist-project ................................... SUCCESS [ 0.112 s]
[INFO] emacsist-kit ....................................... SUCCESS [ 1.186 s]
[INFO] emacsist-email ..................................... SUCCESS [ 0.177 s]
[INFO] emacsist-http ...................................... SUCCESS [ 0.093 s]
[INFO] emacsist-redis ..................................... SUCCESS [ 0.130 s]
[INFO] weibosdk-base ...................................... SUCCESS [ 0.337 s]
[INFO] common-pojo ........................................ SUCCESS [ 0.065 s]
[INFO] weibosdk-dao ....................................... SUCCESS [ 0.231 s]
[INFO] weibosdk-service ................................... SUCCESS [ 0.084 s]
[INFO] weibosdk-redis ..................................... SUCCESS [ 0.137 s]
[INFO] weibosdk-rabbitmq .................................. SUCCESS [ 0.200 s]
[INFO] weibosdk-web ....................................... SUCCESS [ 0.845 s]
[INFO] weibosdk-interceptor ............................... SUCCESS [ 0.148 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.010 s
[INFO] Finished at: 2015-10-16T17:23:27+08:00
[INFO] Final Memory: 33M/314M
[INFO] ------------------------------------------------------------------------