Maven管理(一)
Maven管理(一)
背景描述:
工作中经常维护一些比较老的项目,技术体系十分陈旧。一次两次按照升级需求针对性地改动少量代码完成任务还凑活,当频繁进行改动时就非常令人头大了。许多冗余操作类似:导入额外jar包、根据不同环境改写配置文件等,不但操作繁琐,而且每次部署都需要手动改写7、8个不同配置文件中的若干配置项,很容易出错(线上出了好几次问题-_-I|)。
为了彻底解决这些问题,我决定升级这些代码,其中最核心的操作就是:使用maven管理项目。关于maven的基础知识我再不在赘述了,直接根据我的项目进程总结maven应用。
1.将普通项目转为maven项目
1.1转换项目
在指定文件夹下命令行输入以下内容(也可以使用IDE创建一个空的maven项目):
#自行填入groupId和artifactId
mvn -B archetype:generate \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DgroupId=xxxx \
-DartifactId=xxxx
生成的目录包含一个src
文件夹,一个pom.xml
。
这个路径是普通maven项目的路径,如果是web项目还需要创建resources
存放配置文件,创建webapp
存放web资源。创建完成后后,将所有配置文件放到/resources
下,将web资源(没使用的maven管理的java web项目一般存放在webContent中)复制到web下。然后将项目导入到你的IDE中进行后续处理。excipse导入这样的项目可能会出现一些问题,请注意配置Peoject Facets
和Devlepment Assembly
。
以上操作都可以通过直接创建maven项目然后复制代码完成
1.2修改配置文件路径
- 一般使用tomcat启动web项目需要web.xml,xml中定义了spring相关框架的监听器,注意修改这些路径。
- 一些spring相关框架中可能需要引入property,注意修改路径。
- 使用mybatis或hibernate等持久层框架的项目,注意修改数据映射文件的路径。
2.导入本地jar包
未使用maven管理的web项目一般会把额外jar包放到WEB-INF/lib路径下,我们可以使用maven插件将这些jar包在编译打包的时候直接复制到指定位置,省的你再一个个去写dependency
。
pom.xml配置如下:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
<!--打包本地 jar包 -->
<compilerArguments>
<extdirs>${project.basedir}/src/main/webapp/WEB-INF/lib</extdirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}\classes\lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
3.利用profile
针对不同环境打包
我们十分头疼根据开发、测试、生产不同的环境不停的修改配置文件,这不但非常麻烦而且很容易出错。传统的web项目我们没有什么比较好的解决方法,只能提前准备好不同环境的配置文件不停地去替换,这样就带来保持不同配置文件版本同步的困难。现在我们使用maven的profile
参数进行帮助我们避免这个问题。
在/src/resources
目录下新建test
、product
两个文件夹,把原来/src/resources
下的配置文件复制到这俩目录下各一份,并根据环境的不同改好配置文件。
并在pom.xml
中添加插件:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>compile</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<!-- 覆盖原有文件 -->
<overwrite>true</overwrite>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<!-- 待处理的资源定义 -->
<resources>
<resource>
<!-- 指定resources插件处理哪个目录下的资源文件 -->
<directory>src/main/resources/${package.environment}</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
<inherited></inherited>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warName>${project.artifactId}</warName>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>*.properties</include>
<include>*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
添加参数:
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<package.environment>dev</package.environment>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<package.environment>test</package.environment>
</properties>
</profile>
<profile>
<id>product</id>
<properties>
<package.environment>product</package.environment>
</properties>
</profile>
</profiles>
这个配置的含义是:
pom定义三个参数dev
、test
、product
。在打包时,根据输入的命令参数不同,将相应目录下的配置文件复制并替换/src/resources
下的配置文件。
例如,使用:
mvn package -Pproduct
打包时,maven会将/src/resources/product
路径下的配置文件辅助并替换掉/src/respurces
中的配置文件。这样,生成的war包的/src/resources
中包含的就是生产环境的配置文件了。
4.本地jar包生成pom文件中的dependency
有时候,你不得不把/WEB-INF/lib
下的jar包全部使用maven管理(比如你的领导要求如此)。你不必着急一个个jar包的去查询,我这有个代码拿去抄吧(就是调用接口查询dependency的写法):
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
import org.dom4j.Element;
import org.dom4j.dom.DOMElement;
import org.jsoup.Jsoup;
import com.alibaba.fastjson.JSONObject;
/**
* @author chen_xi_yuan
* @vsersion 2019年11月15日 下午8:34:15
*/
public class TestStatic {
public static void main(String[] args) throws Exception {
genDependicies();
}
public static void genDependicies() throws FileNotFoundException, IOException {
Element dependencys = new DOMElement("dependencys");
// 需生成pom.xml文件的lib路径
File dir = new File("D:/xxx/src/main/webapp/WEB-INF/lib");
for (File jar : dir.listFiles()) {
JarInputStream jis = new JarInputStream(new FileInputStream(jar));
Manifest mainmanifest = jis.getManifest();
jis.close();
if (mainmanifest == null) {
continue;
}
String bundleName = mainmanifest.getMainAttributes().getValue("Bundle-Name");
String bundleVersion = mainmanifest.getMainAttributes().getValue("Bundle-Version");
Element ele = null;
StringBuffer sb = new StringBuffer(jar.getName());
if (bundleName != null) {
bundleName = bundleName.toLowerCase().replace(" ", "-");
sb.append(bundleName + "\t").append(bundleVersion);
ele = getDependices(bundleName, bundleVersion);
}
if (ele == null || ele.elements().size() == 0) {
bundleName = "";
bundleVersion = "";
String[] ns = jar.getName().replace(".jar", "").split("-");
for (String s : ns) {
if (Character.isDigit(s.charAt(0))) {
bundleVersion += s + "-";
} else {
bundleName += s + "-";
}
}
if (bundleVersion.endsWith("-")) {
bundleVersion = bundleVersion.substring(0, bundleVersion.length() - 1);
}
if (bundleName.endsWith("-")) {
bundleName = bundleName.substring(0, bundleName.length() - 1);
}
ele = getDependices(bundleName, bundleVersion);
sb.setLength(0);
sb.append(bundleName + "\t").append(bundleVersion);
// System.out.println(sb.toString());
System.out.println(ele.asXML());
}
ele = getDependices(bundleName, bundleVersion);
if (ele.elements().size() == 0) {
ele.add(new DOMElement("groupId").addText("not find"));
ele.add(new DOMElement("artifactId").addText(bundleName));
ele.add(new DOMElement("version").addText(bundleVersion));
}
dependencys.add(ele);
System.out.println();
}
System.out.println(dependencys.asXML());
}
public static Element getDependices(String key, String ver) {
Element dependency = new DOMElement("dependency");
try {
String url = "http://search.maven.org/solrsearch/select?q=a%3A%22" + key + "%22%20AND%20v%3A%22" + ver
+ "%22&rows=3&wt=json";
org.jsoup.nodes.Document doc = Jsoup.connect(url).ignoreContentType(true).timeout(30000).get();
String elem = doc.body().text();
JSONObject response = JSONObject.parseObject(elem).getJSONObject("response");
if (response.containsKey("docs") && response.getJSONArray("docs").size() > 0) {
JSONObject docJson = response.getJSONArray("docs").getJSONObject(0);
Element groupId = new DOMElement("groupId");
Element artifactId = new DOMElement("artifactId");
Element version = new DOMElement("version");
groupId.addText(docJson.getString("g"));
artifactId.addText(docJson.getString("a"));
version.addText(docJson.getString("v"));
dependency.add(groupId);
dependency.add(artifactId);
dependency.add(version);
}
} catch (Exception e) {
e.printStackTrace();
}
return dependency;
}
}
目前正在尝试maven自动测试,以及持续集成方案。
原文地址:https://www.cnblogs.com/cxy2016/p/12583241.html
- 跨域访问支持(Spring Boot、Nginx、浏览器)
- 自己动手写个聊天机器人吧
- 碎片化 | 第四阶段-37-sturts2-登录功能实现-视频
- Spring Cloud Edgware新特性之六:Artifact ID变更
- 用 RNN 训练语言模型生成文本
- 碎片化 | 第四阶段-38-Struts2登录session对象封装-视频
- LeetCode实战:子问题分析
- 5分钟构建一个自己的无人驾驶车
- 碎片化 | 第四阶段-39-Struts2中session对象梳理-视频
- 用深度神经网络处理NER命名实体识别问题
- 碎片化 | 第四阶段-40-Struts组件分类讲解-视频
- nginx location配置
- 碎片化 | 第四阶段-41-struts2字节流生成验证码-视频
- Python|模块,包,标准模板
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 通过Rxjava看Kotlin协程(一)
- Fuzz中的javascript大小写特性
- 通过RxJava看kotlin协程(二)
- Android 黑科技 |Gradle Plugin使用场景
- php5全版本绕过open_basedir读文件脚本
- CameraX 封装二维码扫描组件
- Kotlin拓展函数的真身
- 一个一年没解决的ClassNotFoundException|类加载机制探索
- 我有个大胆的方案可以提高ARouter和WMRouter的编译速度
- Tornado模板对空白字符的处理与解决方案
- View的有效曝光监控(上)|RecyclerView 篇
- PHP绕过open_basedir列目录的研究
- View的有效曝光监控(下)|ScrollView NestScrollView篇
- 聊聊AbstractProcessor和Java编译流程
- Okhttp如何开启的Http2.0