0%

Maven 常用命令全解析:从基础到进阶操作

Maven 命令是项目构建和管理的核心工具,掌握常用命令能显著提升开发效率。本文将按功能分类梳理 Maven 命令,涵盖基础构建、依赖管理、项目创建、测试与发布等场景,并解释其底层原理和适用场景。

基础构建命令

这类命令对应 Maven 生命周期的核心阶段,用于完成项目的编译、测试、打包等基础操作。

命令 功能描述 底层原理
mvn -v 查看 Maven 版本及环境信息(如 Java 版本、安装路径) 输出 maven-homejava-home 等配置,验证 Maven 环境是否正确。
mvn clean 清理项目(删除 target 目录,即编译、打包生成的文件) 触发 Clean 生命周期的 pre-cleanclean 阶段,调用 maven-clean-plugin:clean 目标。
mvn compile 编译主程序源码(输出到 target/classes 触发 Default 生命周期的 compile 阶段,调用 maven-compiler-plugin:compile 目标。
mvn test-compile 编译测试源码(输出到 target/test-classes 触发 test-compile 阶段,调用 maven-compiler-plugin:testCompile 目标。
mvn test 执行单元测试(运行 src/test/java 中的测试用例) 触发 test 阶段,调用 maven-surefire-plugin:test 目标,默认生成测试报告到 target/surefire-reports
mvn package 打包项目(如 Jar、War,输出到 target 目录) 触发 package 阶段,根据项目类型(pom.xml<packaging>)调用对应插件(如 maven-jar-plugin:jar)。
mvn install 将包安装到本地仓库(供本地其他项目依赖) 触发 install 阶段,调用 maven-install-plugin:install 目标,将包复制到本地仓库(默认 ~/.m2/repository)。
mvn deploy 将包部署到远程仓库(供团队共享) 触发 deploy 阶段,调用 maven-deploy-plugin:deploy 目标,需在 pom.xml 中配置 <distributionManagement> 远程仓库地址。

常用组合命令

1
2
3
4
5
6
7
8
# 清理并打包(跳过测试,适合快速构建)
mvn clean package -DskipTests

# 清理、编译、测试并安装到本地仓库
mvn clean install

# 部署到远程仓库(通常用于发布正式版本)
mvn clean deploy -Pprod # -Pprod 激活生产环境 profile
阅读全文 »

Maven 生命周期详解:从清理到部署的完整流程

Maven 的生命周期是其核心概念之一它定义了项目构建的标准化流程,从代码清理、编译、测试到打包、部署,每个环节都有明确的阶段和职责。理解生命周期有助于开发者掌握 Maven 构建的执行逻辑,高效管理项目流程。本文将系统解析 Maven 的三套套生命周期及其运作机制。

生命周期的本质

Maven 生命周期是一系列有序的阶段(Phase) 的集合,每个阶段代表构建过程中的一个特定步骤(如编译、测试)。其核心特点包括:

  • 抽象定义:生命周期仅定义 “做什么”(如 compile 表示编译源码),不关心 “怎么做”。
  • 插件实现:具体操作由插件的目标(Goal)完成,例如 compile 阶段由 maven-compiler-plugin:compile 目标执行。
  • 顺序执行:执行某个阶段时,Maven 会自动执行该阶段之前的所有阶段。例如执行 mvn package 会先执行 validatecompiletest 等前置阶段。

三套核心生命周期

Maven 包含Clean、Default、Site 三套相互独立的生命周期,每套生命周期专注于不同的构建目标。

Clean 生命周期:清理项目

作用:删除上一次构建生成的文件(如 target 目录),为新构建做准备。

包含三个阶段,执行顺序如下:

阶段 含义 绑定的插件目标
pre-clean 清理前的准备工作(如备份文件) 无默认插件
clean 删除构建目录(默认 target maven-clean-plugin:clean
post-clean 清理后的收尾工作(如删除备份) 无默认插件
阅读全文 »

Hystrix 线程隔离:线程池位置与跨线程上下文传递解析

Hystrix 的线程隔离是通过在调用方服务中维护独立线程池实现的,其核心目的是将不同依赖服务的调用隔离开,避免单个依赖的故障耗尽调用方的线程资源。同时,线程隔离会引入跨线程问题(如ThreadLocal上下文丢失),需通过自定义并发策略解决。

Hystrix 线程池的存在位置

Hystrix 的线程池存在于调用方服务(消费端) 中,由调用方为每个依赖的服务(或服务分组)维护一个独立的线程池。

例如:服务 A 调用服务 B 和服务 C,服务 A 会为服务 B 创建线程池 B,为服务 C 创建线程池 C。当服务 B 响应超时或故障时,线程池 B 的线程可能被耗尽,但线程池 C 仍能正常处理对服务 C 的调用,从而实现 “故障隔离”。

为什么线程池在调用方?

  • 线程隔离的核心是保护调用方的资源不被依赖服务耗尽,因此线程池必须由调用方控制和维护;
  • 若线程池在服务提供方,调用方仍可能因等待响应而耗尽自身线程,无法实现隔离目的。

跨线程上下文丢失问题:ThreadLocal 的 “陷阱”

问题场景

Web 应用中,RequestContextHolder通过ThreadLocal存储请求上下文(如用户登录信息、请求头),但 Hystrix 命令在独立线程池的线程中执行,与 Tomcat 的工作线程(主线程)属于不同线程,导致RequestContextHolder.getRequestAttributes()返回null

阅读全文 »

Spring Boot 注册 Servlet 详解:三种核心方式与实战对比

在 Spring Boot 中,虽然推荐使用 Spring MVC 的 @Controller 处理请求,但在集成传统 Servlet、Filter、Listener(如第三方组件)时,仍需手动注册这些 Servlet 规范组件。从 “@WebServlet 注解→ServletRegistrationBean→动态注册(ServletContextInitializer)” 三个维度,系统讲解 Spring Boot 注册 Servlet 的完整流程,并对比三种方式的适用场景,帮你灵活应对传统组件集成需求。

Servlet 注册的核心背景

Servlet 是 Java EE 规范的核心组件,用于处理 HTTP 请求,传统 Java Web 项目通过 web.xml 配置 Servlet(如 <servlet><servlet-mapping> 标签)。Spring Boot 摒弃了 web.xml,提供了三种更简洁的注册方式,本质都是通过 “编程式配置” 替代 XML 配置,适配嵌入式容器(如 Tomcat)和外置容器。

方式一:@WebServlet 注解(Servlet 3.0+ 原生支持)

Servlet 3.0 规范引入了注解式注册(@WebServlet@WebFilter@WebListener),Spring Boot 支持该规范,只需通过 @ServletComponentScan 开启扫描,即可自动注册标注 @WebServlet 的类。

1. 核心步骤

(1)编写 Servlet 类并标注 @WebServlet
阅读全文 »

ShardingSphere-JDBC读写分离

sharding-jdbc会通过sql语句进行语义分析,如果是insert、update、delete语句会路由到master库进行操作,如果是select语句会路由到slave库进行操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
spring:
application:
name: sharding-jdbc-test
shardingsphere:
datasource:
names: m0,s0 # 配置数据源,给数据源起名
m0: # 主库,配置数据源具体内容,连接池、驱动、地址、用户名、密码
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis?useSSL=false
username: root
password: 123456
s0: # 从库,配置数据源具体内容,连接池、驱动、地址、用户名、密码
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis1?useSSL=false
username: root
password: 123456
# sharding: # 方式一
# master-slave-rules:
# m0:
# master-data-source-name: m0 #配置m0数据库的主库
# slave-data-source-names: s0 #配置m0数据库的从库
masterslave: # 方式二
name: ms
master-data-source-name: m0
slave-data-source-names: s0
load-balance-algorithm-type: round_robin
props:
sql:
show: true # 输出日志