1:何爲Maven座標
爲了能夠自動化地解析任何一個Java構件,Maven就必須要將其唯一標識,這就是依賴管理的底層基礎——座標。
學過數學的人都知道平面直角座標系,x,y分別爲其橫,縱座標,將會在平面直角座標系中唯一的確定一個點。在Maven世界中用戶數量非常巨大的構件,也就是平常用到的jar和war等文件。在Maven爲這些構件引入座標概念之前,我們無法使用任何一種方式來唯一地標識這些構件。只能自己去網上找,浪費時間還容易版本不兼容,基於此,Maven定義了這樣的一組規則:
世界上任何一個構件都可以使用Maven座標唯一標識
Maven座標的元素包括
- groupId
- artifactId
- version
- package
- classifier
所以我們只要能夠提供正確的座標信息,Maven就能幫我們找到對應的構件,Maven會去哪裏找呢?答案是在Maven的構件倉庫中,Maven內置了一箇中央倉庫的地址,該中央倉庫包含了世界上大部分流行的開源項目構件。
不僅如此,在我們自己做開發的時候,也需要爲其定義適當的座標,這是Maven強制要求的,因爲只有這樣,其他Maven項目才能引用該項目生成的構件。見下圖
2:座標詳解
示例:
<groupId>org.sonatype.nexus</groupId>
<artifactId>nexus-indexer</artifactId>
<version>3.0.4</version>
<packaging>jar</packaging>
這是nexus-indexer的座標定義,nexus-indexer是一個針對Maven倉庫編纂索引並提供搜索功能的類庫,是Nexus項目的一個子模塊,後面會介紹。
上述代碼片段中,其座標分別爲:groupId:org.sonatype.nexus,artifactId:nexus-indexer,version:3.0.4,packaging:jar
座標元素解釋:
- groupId
定義當前Maven項目隸屬的實際項目,表示方式與Java包名的表示方式類似,通常與域名反向一一對應。這個就是父項目,其下可以有很多子模塊。
- artifactId
定義實際項目中的一個Maven項目(模塊),推薦的做法是使用實際項目名稱作爲artifaceId的前綴,比如上例中的artifactId是nexus-indexer,使用了實際項目名nexus作爲前綴,這樣做的好處是方便尋找實際構件。
- version
定義Maven項目當前所處的版本,如上例中nexus-indexer的版本是3.0.4,需要注意的是:Maven定義了一套完成的版本規範以及快照(SNAPSHOT)的概念。
- packaging
定義Maven項目的打包方式,首先,打包方式通常與所生成構件的文件擴展名對應,如上例中packaging爲jar,最終的文件名爲:nexus-indexer-3.0.4-jar,而使用war打包方式的Maven項目,最終會生成一個*.war的文件,不過這不是絕對的。其次,打包方式會影響到構建的生命週期,比如jar和war會使用不同的命令。最後,Maven默認jar包。
- classifier
幫助定義構建輸出的一些附屬構建。附屬構件與主構件對應,如上例中的主構件是nexus-indexer-3.0.4.jar,該項目可能還會通過使用一些插件生成如nexus-indexer-3.0.4-javadoc.jar、nexus-indexer-3.0.4-source.jar這樣一些附屬構件,其包含了Java文檔和源碼。這時候,javadoc和source就是這兩個附屬構件的classifier。附屬構件也有自己的唯一座標。
注意:不能直接定義項目的classifier,因爲附屬構件不是項目直接默認生成的,而是由附加的插件生成的。
上述五個元素中,groupId、artifactId、version是必須定義的,packaging是可選的(默認jar),而classifier是不能直接定義的。
3:account-email的pom.xml
基於上一章的背景案例。案例中有一個負責發送賬戶激活的電子郵件,現在就要對該模塊進行實現,包括POM配置、主代碼和測試代碼。基於SpringBoot,因此還會涉及SpringBoot的配置。
pom.xml代碼清單:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.soulprayer.maven.account</groupId> <artifactId>account-email</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>jar</packaging> <name>Account Email</name> <description>Account Email</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--SpringBoot郵件相關--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> <version>1.5.4.RELEASE</version> </dependency> <!--郵件發送相關--> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.7</version> </dependency> <!--單元測試相關,依賴範圍爲測試代碼,不影響主代碼--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>com.icegreen</groupId> <artifactId>greenmail</artifactId> <version>1.5.5</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
4:account-eamil的主代碼
AccountEmailService.java
public interface AccountEmailService { //發送郵件 void sendMail(String to,String subject,String htmlText) throws Exception; }
AccountEmailServiceImpl.java
//注入爲服務 @Service @SuppressWarnings("SpringJavaAutowiringInspection") public class AccountEmailServiceImpl implements AccountEmailService { private final Logger logger = LoggerFactory.getLogger(this.getClass()); //Spring郵件發送工具類庫 @Autowired private JavaMailSender javaMailSender; //注入發件人地址 @Value("${spring.mail.username}") private String systemEmail; @Override public void sendMail(String to, String subject, String htmlText) throws Exception { try { //構建消息 MimeMessage msg = javaMailSender.createMimeMessage();; MimeMessageHelper msgHelper = new MimeMessageHelper(msg,true); //發件地址 msgHelper.setFrom(systemEmail); //收件地址 msgHelper.setTo(to); //主題 msgHelper.setSubject(subject); //內容,true爲Html格式 msgHelper.setText(htmlText,true); javaMailSender.send(msg); logger.info("郵件發送成功!"); }catch (MessagingException e){ throw new Exception("Faild to send mail." + e); } } }
5:account-email的測試代碼
AccountEmailApplicationTests.java
@RunWith(SpringRunner.class) @SpringBootTest public class AccountEmailApplicationTests { @Autowired private AccountEmailService emailService; @Test public void contextLoads() throws Exception { String subject = "Test Subject"; String htmlText = "<h1>This is a mail test!</h1>"; emailService.sendMail("xxxxx@qq.com", subject, htmlText); } }
郵件發送成功JunitTest截圖
郵件發送成功Maven命令截圖
收到的郵件截圖
6:account-email的構建
使用mvn clean install構建account-email,Maven會依據POM配置自動下載所需要的依賴構件,執行編譯、測試、打包等工作,最後將項目生成的構件account-email-1.0.0-SNAPSHOT.jar安裝到本地倉庫中,這時,該模塊就能被其他Maven項目使用了。
7:小結
至此,我們就完成了註冊服務中的郵件模塊了,並且講解了一下Maven的座標體系,本郵件模塊基於SpringBoot完成,如對SpringBoot不瞭解的,可以參考我的
SpringBoot實戰(待寫),希望大家多多鼓勵!。