maven运行原理分析,源码分析

maven启动脚本mvn.bat,借助于Plexus容器启动,Plexus提供完整的软件栈,用于创建和执行软件项目,是IoC框架,和spring类似

有兴趣想了解Plexus的,可以在github上下载代码,https://github.com/codehaus/plexus.git

boot目录下的plexus-classworlds-2.5.2.jar文件就是Plexus包

set CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher

%MAVEN_JAVA_EXE%%MAVEN_OPTS% -classpath %CLASSWORLDS_JAR%

"-Dclassworlds.conf=%M2_HOME%\bin\m2.conf"

"-Dmaven.home=%M2_HOME%"%CLASSWORLDS_LAUNCHER% %MAVEN_CMD_LINE_ARGS%

m2.conf配置文件

main isorg.apache.maven.cli.MavenCli from plexus.core

setmaven.home default ${user.home}/m2

[plexus.core]

optionally${maven.home}/lib/ext/*.jar

load       ${maven.home}/lib/*.jar

load       ${maven.home}/conf/logging

org.apache.maven.cli.MavenCli类就是maven启动的入口方法,Plexus通过读取m2.conf配置文件,反射invoke,org.apache.maven.cli.MavenCli类的main方法

 
  1. try

  2. {

  3. initialize( cliRequest );//初始化工作目录变量,以及maven.home变量

  4. cli( cliRequest );// 解析commandLine参数

  5. logging( cliRequest );//配置日志,是否-X开启debug日志,是否-q只显示错误日志

  6. version( cliRequest );//打印maven版本信息

  7. properties( cliRequest );//装载systemProperties、userProperties、buildProperties

  8. localContainer = container(cliRequest );//创建IoC容器,并获取maven等必要类实例

  9. commands( cliRequest );//打印部分状态信息

  10. settings( cliRequest );//加载settings.xml文件,包含globalsettings和user settings,然后进行merge合并

  11. populateRequest( cliRequest );//装配请求对象

  12. encryption( cliRequest );//deploy时候需要setting.xml里面存明文密码,此处可以把密码加密保存

  13. repository( cliRequest );//处理是否使用LegacyLocalRepository仓库

  14. return execute( cliRequest );//真正执行的地方

  15. }

  16. catch ( ExitException e )

  17. {

  18. return e.exitCode;

  19. }

下面主要分析下DefaultMaven类中doExecute方法

1.        初始化属性

2.        验证本地仓库目录是否存在或是否可以访问

validateLocalRepository(request );

3.        创建RepositorySystemSession,带有authentication,mirror, proxy和其它系统环境信息

newRepositorySession(request ) ;

4.        创建MavenSession,带有容器,RepositorySystemSession,请求对象,返回结果对象

newMavenSession( container, repoSession, request, result );

5.        执行AbstractLifecycleParticipant.afterSessionStart(session)

6.        获取依赖的项目,检查是否有pom错误

projects= getProjectsForMavenReactor( session );

validateProjects(projects );

7.        创建ProjectDependencyGraph,带有剪裁反应堆,如:-pl,-rf

//获取经过依赖关系进行排序之后的模块结合

activeProjects= projectDependencyGraph.getSortedProjects();

//获取-pl指定的以及所依赖的

activeProjects= trimSelectedProjects( activeProjects, projectDependencyGraph, request );

//排除指定的模块-pl !xxx

activeProjects= trimExcludedProjects( activeProjects, request );

//从-rf指定的模块开始

activeProjects= trimResumedProjects( activeProjects, request );

8.        创建ReactorReader,用于查找maven反应堆模块

reactorWorkspace= container.lookup( WorkspaceReader.class, ReactorReader.HINT );

9.        执行AbstractLifecycleParticipant.afterProjectsRead(session)

10.    创建ProjectDependencyGraph,不带剪裁

11.    执行LifecycleStarter.start(),开始执行生命周期任务

lifecycleStarter.execute(session );

分析LifecycleStarter类中,execute方法

//计算任务,如:clean,package,install,deploy

taskSegments= lifecycleTaskSegmentCalculator.calculateTaskSegments( session );

//计算执行任务的模块,就是哪些模块需要执行以上任务

projectBuilds= buildListCalculator.calculateProjectBuilds( session, taskSegments );

//执行任务,内部两层循环,依据任务列表和模块列表循环执行

builder.build(session, reactorContext, projectBuilds, taskSegments, reactorBuildStatus );

以下是calculateProjectBuilds方法执行的结果:

[DEBUG]=== REACTOR BUILD PLAN ================================================

[DEBUG]Project: org.apache.maven:maven:pom:3.2.5

[DEBUG]Tasks:   [clean]

[DEBUG]Style:   Regular

[DEBUG]-----------------------------------------------------------------------

[DEBUG]Project: org.apache.maven:maven-model:jar:3.2.5

[DEBUG]Tasks:   [clean]

[DEBUG]Style:   Regular

[DEBUG]-----------------------------------------------------------------------

[DEBUG]Project: org.apache.maven:apache-maven:pom:3.2.5

[DEBUG]Tasks:   [clean]

[DEBUG]Style:   Regular

[DEBUG] =======================================================================

下一步则是DefaultBuildPluginManager类中executeMojo()方法执行具体的mojo插件的execute方法:mojo.execute();

  1. publicinterface Mojo

  2. {

  3. String ROLE = Mojo.class.getName();

  4. void execute() throws MojoExecutionException,MojoFailureException;

  5. void setLog( Log log );

  6. Log getLog();

  7. }

maven插件开发,需要继承AbstractMojo类,而此类则实现了Mojo接口。

猜你喜欢

转载自blog.csdn.net/qq_36838191/article/details/82346590