1.确认自己无法直接访问公共的Maven中央仓库:ping repo1.maven.org
2.检查代理服务器是否畅通:telnet xxx.xxx.xxx.xxx xxxx如果连接正确刚ctrl+],然后按q,退出。
然后在settings.xml中配置如下:
<settings> ... <proxies> <proxy> <id>my_proxy</id> <active>true</active> <protocol></protocol> <host></host> <port></port> <username></username> <password></password> <nonProxyHosts></nonProxyHosts><!--过滤掉不需要代理的网址--> </proxy> </proxies> ... </settings>
配置maven-compile-plugin支持java 5
<project> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compile-plugin</artifactId> <configuration> <scope>1.5</scope> <target>1.5</target> </configuration> </plugin> </plugins> </build> ... </project>
当代码中有main方法时,默认的打包生成的jar无法直接运行,因为带有main方法的类信息不会加到mainfest中(jar文件中META-INF/MAINFEST.MF文件,将无法看到Main-Class一行)。为了生成可执行的jar文件,要配置maven-shade-plugin:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>1.2.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.MainfestResourceTransformer"> <mainClass></mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
Maven有三种classpath(compile,test,runtime)
Maven有以下几种依赖范围来控制依赖与这三种classpath的关系:
Compile:编译依赖范围。如果没有指定,就会默认使用该依赖范围的Maven依赖,对于编译、测试、运行三种classpath都有效。典型的例子是spring-core,在编译、测试和运行的时候都要使用该依赖。
Test:测试依赖范围。使用此依赖范围的Maven依赖,只对于测试classpath有效,在编译主代码或者运行项目的使用时将无法使用此类依赖。典型的例子是JUnit,它只有在编译测试代码及运行测试的时候才需要。
Provided:已提供依赖范围。使用此依赖范围的Maven依赖,对于编译和测试classpath有效,但在运行时无效。典型的例子是servlet-api,编译和测试项目的时候需要该依赖,但在运行项目的时候,由于容器已经提供,就不需要Maven重复的引入一遍。
Runtime:运行时依赖范围 。使用此依赖范围的Maven依赖,对于测试和运行classpath有效,但在编译主代码时无效。典型的例子是JDBC驱动实现,项目主代码主编译只需要JDK提供的JDBC接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体 JDBC驱动。
System:系统依赖范围。该依赖与3种classpath的关系 ,和Proveided依赖范围 完全一致。但是,使用System范围 的依赖时必须通过systemPath元素显式地指定依赖文件的路径。由于此类依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用。systemPath元素可以引用环境变量如:
<dependency> <groupId>javax.sql</groupId> <artifactId>jdbc-stdext</artifactId> <scope>system</scope> <systemPath>${java.home}/lib/rt.jar</systemPath> </dependency>
Import(Maven 2.0.9及以上):导入依赖范围。该依赖范围不会对3种classpath产生实际的影响。
传递性依赖和依赖范围:
假设A依赖于B,B依赖于C,我们说A与B是第一直接依赖,B与C是第二直接依赖,A与C是传递性依赖。
传递性依赖范围:
- 1.当第二直接依赖的范围是compile时,传递性依赖的范围与第一直接依赖的范围一致;
- 2.当第二直接依赖的范围是test时,依赖不会得以传递;
- 3.当第二直接依赖的范围是provided时,只传递第一直接依赖也是provided的依赖,且传递性依赖的范围同样是provided
依赖调解(Dependency Mediation)
依赖调解的两项原则:
- 1.路径最近者优先;
- 2.最先声明者优先。
排除依赖:
由于某些原因,想替换某个传递性依赖或者去掉一些不稳定性的依赖时就要使用排除依赖。
<project> <modelVersion></modelVersion> <groupId></groupId> <artifactId></artifactId> <version></version> <dependencies> <dependency> <groupId></groupId> <artifactId></artifactId> <version></version> <exclusions> <exclusion> <groupId></groupId> <artifactId></artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId></groupId> <artifactId></artifactId> <version></version> </dependency> </dependencies> </project>
归类依赖:
当依赖来自同一项目的不同模块时,这些依赖的版本都是相同的,而且可以预见,如果将来需要升级,这些依赖的版本会一起升级那么就应该使用归类依赖来减少错误,方便管理。用法如下:
<project> <modelVersion></modelVersion> <groupId></groupId> <artifactId></artifactId> <version></version> <properties> <springframework.version>2.5.6</springframework.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${springframework.version}</version> </dependency> ... </dependencies> </project>
优化依赖:
在软件开发过程中,程序员会通过重构等方式不断优化自己的代码,使其变得更简洁、更灵活。同理,程序员也应该能够对Maven项目的依赖了然于胸,并对其进行优化,如去除多余的依赖,显式地声明某些必要的依赖。
Maven会自动解析所有项目的直接依赖和传递性依赖,并且根据规则正确判断每个依赖的范围,对于一些依赖冲突,也能进行调节,以确保任何一个构件只有唯一的版本在依赖中存在。在这些工作之后,最后得到的那些依赖被称为已解析依赖(Resolved Dependency)。可以运行如下命令查看当前项目的已解析依赖:
mvn dependency:list
在此基础上,还能进一步了解已解析依赖的信息。将直接在当前项目POM声明的依赖定义为顶层依赖,而这些顶层依赖的依赖则定义为第二层依赖,以此类推。当这些依赖经Maven解析后,就会构成一个依赖树,通过为样依赖树能很清楚地看到某个依赖是通过 哪条路径引入的。查看当前项目的依赖树命令为:
mvn dependency:tree
在此基础上,还有dependency:analyze工具可以帮助分析当前项目的依赖。
显示结果中重要的两个部分:
- 1.Used undeclared dependencies意指项目中使用但是没有显式声明的依赖。
- 2.Used decalared dependencies意指项目是未使用的但是显式声明的依赖。这里列出的要小心分析,因为dependency:analyze只会分析编译主代码和测试代码需要用到的依赖,一些执行测试和运行时需要的依赖它发现不了。