maven用可以利用如下配置进行资源过滤,pom.xml的配置如下:
<build> <!-- 主资源目录 --> <resources> <resource> <!-- 设定主资源目录 --> <directory>src/main/resources</directory> <!-- maven default生命周期,process-resources阶段执行maven-resources-plugin插件的resources目标处理主资源目下的资源文件时,只处理如下配置中包含的资源类型 <includes> <include>*.xml</include> </includes> --> <!-- maven default生命周期,process-resources阶段执行maven-resources-plugin插件的resources目标处理主资源目下的资源文件时,不处理如下配置中包含的资源类型(剔除下如下配置中包含的资源类型) <excludes> <exclude>*.xml</exclude> </excludes> --> <!-- maven default生命周期,process-resources阶段执行maven-resources-plugin插件的resources目标处理主资源目下的资源文件时,指定处理后的资源文件输出目录,默认是${build.outputDirectory}指定的目录 <targetPath>d:/</targetPath> --> <!-- maven default生命周期,process-resources阶段执行maven-resources-plugin插件的resources目标处理主资源目下的资源文件时,是否对主资源目录开启资源过滤 --> <filtering>true</filtering> </resource> </resources> </build>
利用这个特性可以解决开发跟生产环境数据库连接配置等问题,但有时这个特性并不符合实际。比如,开发环境我们使用tomcat应用服务器,使用 dbcp数据源,但是生产则使用jboss应用服务器,使用jndi来管理数据源。开发环境跟生产环境spring容器中对于 id=dataSources的bean的配置如下所示:
开发环境:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" /> <property name="url" value="jdbc:oracle:thin:@localhost:1521:gbst" /> <!-- 开发库 --> <property name="username" value="admin" /> <property name="password" value="admin" /> <property name="initialSize" value="1"/> <property name="maxActive" value="2"/> </bean>
生产环境:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>PrdDS</value> </property> <property name="resourceRef"> <value>false</value> </property> </bean>
像这种情况,靠<build><resources><resource>的资源过滤功能就不太实用 了,这时可以采用resources插件的copy-resources目标进行资源copy,来达到分别配置开发环境与生产环境的数据库连接信息及其它 一些配置(缓存服务器地址、短信网关系统连接配置等等),下面分步骤来达到这一目的。
第一步,实用maven穿件一个maven 工程(maven-demo),工程结构如下图:
第二部,在resources下定义spring的配置文件、log4j.properties等文件,并同时在main目录下创建一个 deploy的目录,在deploy目录下创建一个prd的目录,然后在prd的目录下也定义一个spring的配置文件、log4j的文件,文件名相 同,只是里面的配置的内容不同。添加文件后的maven-demo工程目录结构如下图:
main/resoures下的spring配置文件内容如下:
<?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:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 开发环境采用tomcat应用服务器,dbcp数据源管理 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="url" value="jdbc:oracle:thin:@localhost:1521:shell"/> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/> <property name="username" value="scott"/> <property name="password" value="admin123"/> <property name="initialSize" value="1"/> <property name="maxActive" value="2"/> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> </beans>
main/deploy/prd目录下的spring配置文件内容如下:
<?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:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>prdDS</value> </property> <property name="resourceRef"> <value>false</value> </property> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> </beans>
(log4j.properties内容就不列出了,如果要想使得开发环境跟生产环境不一样的配置,原理跟spring的配置文件一样的)
第三步,配置pom.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <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> <groupId>com.shell.maven.demo</groupId> <artifactId>maven-demo</artifactId> <version>1.0.0-SNAPSHOT</version> <name>maven-demo</name> <url>http://maven.apache.org</url> <properties> <!-- system property --> <encoding>UTF-8</encoding> <maven.test.skip>true</maven.test.skip> <skipTests>true</skipTests> <!-- spring版本 --> <springframework.version>3.1.0.RELEASE</springframework.version> </properties> <profiles> <profile> <id>prd</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.6</version> <executions> <execution> <id>copy-resources</id> <!-- 在default生命周期的 validate阶段就执行resources插件的copy-resources目标 --> <phase>validate</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <!-- 指定resources插件处理资源文件到哪个目录下 --> <outputDirectory>${project.build.outputDirectory}</outputDirectory> <!-- 也可以用下面这样的方式(指定相对url的方式指定outputDirectory) <outputDirectory>target/classes</outputDirectory> --> <!-- 待处理的资源定义 --> <resources> <resource> <!-- 指定resources插件处理哪个目录下的资源文件 --> <directory>src/main/deploy/prd</directory> <!-- 指定不需要处理的资源 <excludes> <exclude>WEB-INF/*.*</exclude> </excludes> --> <!-- 是否对待处理的资源开启过滤模式 (resources插件的copy-resources目标也有资源过滤的功能,这里配置的 这个功能的效果跟<build><resources><resource>下配置的资源过滤是一样的,只不过可能执行的阶段不一样, 这里执行的阶段是插件指定的validate阶段,<build><resources><resource>下的配置将是在resources插件的resources目标执行时起作用(在process-resources阶段))--> <filtering>false</filtering> </resource> </resources> </configuration> <inherited></inherited> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles> <repositories> <repository> <id>myRepo</id> <name>myRepo Repository</name> <url>http://maven.infinitus.com.cn:8081/nexus/content/groups/public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>myRepo</id> <name>myRepo Repository</name> <url>http://maven.infinitus.com.cn:8081/nexus/content/groups/public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> </pluginRepositories> <build> <!-- <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> --> <plugins> <!-- 指定在jdk1.6环境下编译 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> <dependencies> <!-- spring 有关jar --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${springframework.version}</version> </dependency> <!-- oracle 驱动 --> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.2.0.3.0</version> </dependency> <!-- 采用dbcp数据源 --> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <!-- comomons jar --> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2</version> </dependency> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.8.3</version> </dependency> </dependencies> </project>
resources插件的目标共有三个,见下图:(截图自Apache官网)
分别是resources目标 testResources目标 及copy-resources目标。
resources目标默认绑定到了default生命周期的process-resources阶段, testResources目标默认绑定到了default生命周期的 process-test-resources阶段。default生命周期阶段及resources插件这两个目标绑定的阶段和主要作用见下图:
对于上图中说到的这两个插件目标的主要功能需要进行一下补充:
如果配置了如下代码,那么这个时候resources插件的resources目标会进行资源过滤处理,pom.xml配置如下:
<build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </build>
同样,如果配置了如下代码,那么这个时候resources的testResources目标会进行资源过滤处理,pom.xml配置如下:
<build> <testResources> <testResource> <directory>src/test/resources</directory> <filtering>true</filtering> </testResource> </testResources> </build>
现在回到讲解resources插件的copy-resources目标上来,这个插件目标有两项内容是必须配置的,见下图:
resources插件的resources目标跟testResources目标都只有outputDirectory一个必 须的配置项(都表示要讲资源文件处理到那个目录下去),而copy-resources目标多了一个resources的必须配置项,我个人的理解是这样 的。首先这个resources配置项也是用来处理资源的,也包含资源过滤等功能,而copy-resources插件目标往往需要配置到 resources插件目标及testResources插件目标的绑定的阶段的前面的阶段去执行,所以在resources插件目标还没有起作用执行 时,可以利用copy-resources的resources必须配置项做一些预处理,比如资源过滤等 (这里的resources必须项配置了之后由copy-resoueces插件目标来执行, 与<build><resources><resources>下的配置没有直接关系,而且互不干涉。可以这么去理 解,在main/deploy/prd下的spring配置文件,如果里面也有一些内容是用${properties}来写的,那里在copy- resources插件目标执行拷贝操作前做一个资源过滤的处理,这个功能实现就得靠copy-resouces插件目标的resources必须配置项 来完成了) 。
第四步,验证效果。先运行mvn clean install命令,然后查看applicationContext.xml文件的内容,再运行mvn clean install -P prd 命令,然后查看applicationContext.xml文件的内容,比较两次有何不同。
执行mvn clean install命令如下图:
运行成功,如下图:
编译成功后查看编译后的applicationContext.xml文件内容,如下图:
从图中可以看到,id=dataSource的配置是开发环境的。
现在运行mvn clean install -P prd命令,如下图:
运行成功,如下图:
此时再来查看编译后的applicationContext.xml文件的内容,如下图:
从上图中可以看到,applicationContext.xml文件被替换成生产环境下的了。
以上就是resources插件的copy-resources插件目标的作用。对于该插件目标下的resources必须配置项的验证,有兴趣的可以敲代码验证。