回顾《Maven学习笔记(一):Maven基础(基于命令行的学习和应用)》
|
一、创建Maven工程
Maven工程创建之后,本质上就是一个独立的工程,我这里简称为”单工程“结构;
通过对pom文件的“继承和聚合”,让Maven工程具备了更高级的特性——工程模块管理;
而相对于命令行,在IDEA中将更容易上手。
(0)设置Maven
- 在IDEA中,设置Maven环境非常简单,进入设置页面有两种方法:一是在Maven选项卡中选中扳手,选择
Maven Settings
就可以进入;二是File
>Settings…
>Build,Execution,Deployment
>Build Tools
>Maven
; - 默认配置如下面第2张图,但是我们一般会选择使用自己安装的Maven路径和settings.xml,或者至少将仓库改为非系统盘;
- 下图是本次学习笔记场景下的Maven配置,三个参数都做了修改;
- 当然,也可以给所有新项目设置一个通用的配置,如下则是我工作环境下一直使用的配置。
- 配置完成后,点击
Apply
或ok
,会自动加载;工作中引入依赖或修改可以手动点击Maven选项卡中的刷新按钮或者按快捷键Ctrl + Shift + M
;一些版本可以配置自动导包,大概在下2图的位置(我的版本是IntelliJ IDEA 2021.1.1 (Ultimate Edition)
未找到该配置)。
(1)Maven单工程
这里所说的创建Maven单工程,对应的命令是mvn archetype:generate
,生成一个标准结构的Java工程;
- 如果在项目选项卡页面(
Welcome to IntelliJ IDEA
),点击New Project
按钮,在右侧项目类型中,选择Maven
创建新的Maven项目;不要选择Create from archetype
,直接点击Next
;
- 进入
New Project
页面,输入对应内容,点击Finish
会创建并自动进入项目;这里项目名称为ideademo01
- 最终生成的工程结构及pom文件如下,与命令行生成稍有不同,但是工程结构是相同的;
- 如果在已经进入项目的状态,直接点击
File
>New
>Project…
,步骤与上述2
相同。
(2)Maven父/子工程
Q:在实际项目中,通常按照业务功能将项目拆分为多个Maven工程,每个工程单独构建将会非常难管理,那么如何有效管理这些工程呢?
A:实践是用一个工程作为其他工程的父工程来管理这些工程。而用作父工程,packaging打包方式配置为pom,且工程结构中只需要保留pom.xml,不再需要其他目录;代码都在子工程中进行编写。
现在,我们将ideademo01
改造为父工程,在其中创建2个子工程;
- 在
ideademo01
项目中,选中ideademo01
右键New
Module…
;或选中ideademo01,点击菜单栏中的File
New
Module…
- 在
New Module
页面parent选择父工程,并给子工程命名(这里的GroupId会继承父工程的GroupId),点击Finish
完成创建;
- 此时项目结构如下图所示(
ideademo01
的打包方式packaging已经修改为pom
,表示它是一个父工程;tools
的pom文件中包含parent标签指向ideademo01
表示其tools为子工程):
- 再按照创建tools的方法创建一个子工程service;
- 删除父工程的
src
目录,因为父工程只需要管理子工程,现在整个项目结构如下
(3)Maven Web工程
如今Java作为Web服务端开发语言的重要地位一直备受业界认可,那么Maven如何创建一个Web工程是JavaWeb开发的重要一步。
在(2)
中,我们已经得到了一个具有Maven父子工程结构的普通Java工程,下面我们要将ideademo01
改造成一个符合JavaWeb开发的Web工程:
- 新建一个Maven工程
startup
备用作为启动工程
- 将
startup
改造成Web工程,选择对应工程
- 修改这两个web资源地址,修改路径如下,主要是将
web
修改为src\main\webapp
,然后点击Apply
- 此时底部会出现一个警告标识,点击Create Artifact,或者自行去Artifacts选项下创建
- 最终工程结构如下
- 修改startup的pom文件,将其打包方式改为war,适用于tomcat部署;再将需要打包的工程引入进来。
- 到此为止,一个常用的web工程已经创建完毕,下面我们执行父工程Maven选项下的命令,就可以将所有工程编译打包。我们来验证一下:
|
|
二、执行Maven命令
- 在IDEA视窗的右侧找到Maven标签页,这里有一个Lifecycle就是我们所说的生命周期,双击对应命令就可以执行;
- 父工程执行会自动执行所有的子工程,子工程执行不影响父工程,但是如果依赖其他还未构建的工程,则可能出现编译报错(因为依赖工程还未编译,或本地仓库中还没有这个jar包);
- 也可以在上面点击 m 手动输入命令(如组合命令
mvn clean install
),回车执行,需要注意的是,默认是父工程,如果只要在子工程执行,要手动在输入框右侧切换下目标工程;
- 上面就是实践中常用的执行方式,在IDEA中其实只需要知道在哪里执行Maven命令,更重要的是明白其中的原理。如果想知道其他执行Maven命令方式,请查询 在IDEA中Maven执行的几种方式
- 当然,在实践中,我们常用的编译、测试和打包,通常会与持续集成(CI)和持续部署(CD)相结合
- DevOps(Development和Operations的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。
- DevOps 是一种软件开发实践,可促进开发与操作之间的协作,从而更快、更可靠地交付软件。DevOps 通常被称作一种文化,它将人员、流程和方法连接在一起来提供持续价值。
- CI代表持续集成(Continuous Integration),而CD代表持续部署(Continuous Deployment)或持续交付(Continuous Delivery)。持续集成强调开发人员提交新代码后,自动进行构建和测试,确保新代码与现有代码兼容。持续部署则是将通过测试的软件部署到生产环境,而持续交付则更进一步,确保软件可以随时部署到生产环境。
- DevOps是一种软件开发方法,旨在通过自动化和协作加速软件交付。它涉及开发团队和运维团队的紧密合作,通过自动化流程使得软件构建、测试、发布更加快捷、频繁和可靠。DevOps的实现依赖于持续集成和持续部署等实践,从而提高了软件交付的速度和质量。
- 常用技术:Git、GitLab、Jenkins、docker、k8s……
三、其他信息
(1)在IDEA中,有几个地方可以执行Maven命令?
4个。
1、Maven选项卡(右侧),对应Maven工程下的Lifecycle下;
2、Maven选项卡(右侧),对应Maven工程下的Plugins下,点开对应插件下的目标;
3、Maven选项卡(右侧),菜单栏的m
图标,点开后直接输入命令或命令组合,回车执行;
4、Project选项卡(左侧),队形工程下的pom.xml
文件右击,选择Run Maven
,选择命令。
(2)如果创建的工程没有生效,该怎么处理
一般是三个特殊状态的目录,新建Maven工程会自动配置好,分别是src\main\java
对应Sources
、src\main\resources
对应Resources
、src\test\java
对应Tests
如果新建工程时没有上述3个目录没有状态,可能是Maven本地仓库未下载到对应插件、或者远程仓库存在连接问题
当然也可以自己手动创建,打开Project Structure
> Modules
,选中需要配置的工程,如下图:
(3)IDEA与Maven版本的问题
IDEA版本:IntelliJ IDEA 2021.1.1 (Ultimate Edition),Maven版本:3.8.5/3.9.9,执行Reload All Maven Projects
导包报错:
而修改为Maven自带的Bundled版本3.6.3可以成功导入(后下载该版本也可以),所以可以根据Bundled来确定IDEA适配的Maven版本,当然也可以尝试升级到最新稳定版
java.lang.RuntimeException: java.lang.RuntimeException: org.codehaus.plexus.component.repository.exception.ComponentLookupException: com.google.inject.ProvisionException: Unable to provision, see the following errors: 1) Error injecting constructor, java.lang.NoSuchMethodError: org.apache.maven.model.validation.DefaultModelValidator: method <init>()V not found at org.jetbrains.idea.maven.server.embedder.CustomModelValidator.<init>(Unknown Source) while locating org.jetbrains.idea.maven.server.embedder.CustomModelValidator at ClassRealm[plexus.core, parent: null] (via modules: org.eclipse.sisu.wire.WireModule -> org.eclipse.sisu.plexus.PlexusBindingModule) while locating org.apache.maven.model.validation.ModelValidator annotated with @com.google.inject.name.Named(value=ide) 1 error role: org.apache.maven.model.validation.ModelValidator roleHint: ide at org.jetbrains.idea.maven.server.Maven3XServerEmbedder.getComponent(Maven3XServerEmbedder.java:514) at org.jetbrains.idea.maven.server.Maven3XServerEmbedder.customizeComponents(Maven3XServerEmbedder.java:609) at org.jetbrains.idea.maven.server.Maven3XServerEmbedder.customize(Maven3XServerEmbedder.java:571) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357) at sun.rmi.transport.Transport$1.run(Transport.java:200) at sun.rmi.transport.Transport$1.run(Transport.java:197) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:196) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) at java.rmi/sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:303) at java.rmi/sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:279) at java.rmi/sun.rmi.server.UnicastRef.invoke(UnicastRef.java:164) at java.rmi/java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:217) at java.rmi/java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:162) at com.sun.proxy.$Proxy200.customize(Unknown Source) at jdk.internal.reflect.GeneratedMethodAccessor792.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at com.intellij.execution.rmi.RemoteUtil.invokeRemote(RemoteUtil.java:150) at com.intellij.execution.rmi.RemoteUtil.access$400(RemoteUtil.java:21) at com.intellij.execution.rmi.RemoteUtil$1.lambda$invoke$0(RemoteUtil.java:134) at com.intellij.openapi.util.ClassLoaderUtil.computeWithClassLoader(ClassLoaderUtil.java:31) at com.intellij.execution.rmi.RemoteUtil.executeWithClassLoader(RemoteUtil.java:202) at com.intellij.execution.rmi.RemoteUtil$1.invoke(RemoteUtil.java:134) at com.sun.proxy.$Proxy200.customize(Unknown Source) at org.jetbrains.idea.maven.server.MavenEmbedderWrapper.doCustomize(MavenEmbedderWrapper.java:83) at org.jetbrains.idea.maven.server.MavenEmbedderWrapper.onWrappeeCreated(MavenEmbedderWrapper.java:36) at org.jetbrains.idea.maven.server.RemoteObjectWrapper.getOrCreateWrappee(RemoteObjectWrapper.java:42) at org.jetbrains.idea.maven.server.MavenEmbedderWrapper.doCustomize(MavenEmbedderWrapper.java:83) at org.jetbrains.idea.maven.server.MavenEmbedderWrapper.lambda$customizeForResolve$1(MavenEmbedderWrapper.java:56) at org.jetbrains.idea.maven.server.RemoteObjectWrapper.perform(RemoteObjectWrapper.java:76) at org.jetbrains.idea.maven.server.MavenEmbedderWrapper.customizeForResolve(MavenEmbedderWrapper.java:55) at org.jetbrains.idea.maven.project.MavenProjectResolver.resolve(MavenProjectResolver.java:77) at org.jetbrains.idea.maven.project.MavenProjectsProcessorResolvingTask.perform(MavenProjectsProcessorResolvingTask.java:45) at org.jetbrains.idea.maven.project.MavenProjectsProcessor.doProcessPendingTasks(MavenProjectsProcessor.java:146) at org.jetbrains.idea.maven.project.MavenProjectsProcessor$1.run(MavenProjectsProcessor.java:115) at org.jetbrains.idea.maven.utils.MavenUtil.lambda$runInBackground$6(MavenUtil.java:536) at com.intellij.util.RunnableCallable.call(RunnableCallable.java:20) at com.intellij.util.RunnableCallable.call(RunnableCallable.java:11) at com.intellij.openapi.application.impl.ApplicationImpl$1.call(ApplicationImpl.java:265) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:668) at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:665) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:665) at java.base/java.lang.Thread.run(Thread.java:834) Caused by: java.lang.RuntimeException: org.codehaus.plexus.component.repository.exception.ComponentLookupException: com.google.inject.ProvisionException: Unable to provision, see the following errors: 1) Error injecting constructor, java.lang.NoSuchMethodError: org.apache.maven.model.validation.DefaultModelValidator: method <init>()V not found at org.jetbrains.idea.maven.server.embedder.CustomModelValidator.<init>(Unknown Source) while locating org.jetbrains.idea.maven.server.embedder.CustomModelValidator at ClassRealm[plexus.core, parent: null] (via modules: org.eclipse.sisu.wire.WireModule -> org.eclipse.sisu.plexus.PlexusBindingModule) while locating org.apache.maven.model.validation.ModelValidator annotated with @com.google.inject.name.Named(value=ide) 1 error role: org.apache.maven.model.validation.ModelValidator roleHint: ide at org.codehaus.plexus.DefaultPlexusContainer.lookup(DefaultPlexusContainer.java:267) at org.codehaus.plexus.DefaultPlexusContainer.lookup(DefaultPlexusContainer.java:243) at org.jetbrains.idea.maven.server.Maven3XServerEmbedder.getComponent(Maven3XServerEmbedder.java:511) at org.jetbrains.idea.maven.server.Maven3XServerEmbedder.customizeComponents(Maven3XServerEmbedder.java:609) at org.jetbrains.idea.maven.server.Maven3XServerEmbedder.customize(Maven3XServerEmbedder.java:571) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357) at sun.rmi.transport.Transport$1.run(Transport.java:200) at sun.rmi.transport.Transport$1.run(Transport.java:197) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:196) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Caused by: java.lang.RuntimeException: com.google.inject.ProvisionException: Unable to provision, see the following errors: 1) Error injecting constructor, java.lang.NoSuchMethodError: org.apache.maven.model.validation.DefaultModelValidator: method <init>()V not found at org.jetbrains.idea.maven.server.embedder.CustomModelValidator.<init>(Unknown Source) while locating org.jetbrains.idea.maven.server.embedder.CustomModelValidator at ClassRealm[plexus.core, parent: null] (via modules: org.eclipse.sisu.wire.WireModule -> org.eclipse.sisu.plexus.PlexusBindingModule) while locating org.apache.maven.model.validation.ModelValidator annotated with @com.google.inject.name.Named(value=ide) 1 error at com.google.inject.internal.InternalProvisionException.toProvisionException(InternalProvisionException.java:226) at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1053) at org.eclipse.sisu.inject.LazyBeanEntry.getValue(LazyBeanEntry.java:81) at org.eclipse.sisu.plexus.LazyPlexusBean.getValue(LazyPlexusBean.java:51) at org.codehaus.plexus.DefaultPlexusContainer.lookup(DefaultPlexusContainer.java:263) ... 21 more Caused by: java.lang.NoSuchMethodError: org.apache.maven.model.validation.DefaultModelValidator: method <init>()V not found at org.jetbrains.idea.maven.server.embedder.CustomModelValidator.<init>(CustomModelValidator.java:36) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.google.inject.internal.DefaultConstructionProxyFactory$ReflectiveProxy.newInstance(DefaultConstructionProxyFactory.java:126) at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:114) at com.google.inject.internal.ConstructorInjector.access$000(ConstructorInjector.java:32) at com.google.inject.internal.ConstructorInjector$1.call(ConstructorInjector.java:98) at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112) at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:127) at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66) at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:93) at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:306) at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1050) at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1086) at org.eclipse.sisu.space.AbstractDeferredClass.get(AbstractDeferredClass.java:48) at com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:85) at com.google.inject.internal.InternalFactoryToInitializableAdapter.provision(InternalFactoryToInitializableAdapter.java:57) at com.google.inject.internal.ProviderInternalFactory$1.call(ProviderInternalFactory.java:66) at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:112) at org.eclipse.sisu.bean.BeanScheduler$CycleActivator.onProvision(BeanScheduler.java:230) at com.google.inject.internal.ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:120) at com.google.inject.internal.ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66) at com.google.inject.internal.ProviderInternalFactory.circularGet(ProviderInternalFactory.java:61) at com.google.inject.internal.InternalFactoryToInitializableAdapter.get(InternalFactoryToInitializableAdapter.java:47) at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40) at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:168) at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:39) at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1050) ... 24 more
下篇预告:《Maven学习笔记(三):Maven基础实践》