前言
我們都知道軟件開發是工科,不是理科;本質上和電工、鉗工是一樣的。
也就是說,軟件技術成長也與電工、鉗工的技術成長是一樣的,靠的是練,而不是學。
所以,很多時候,我們稱應屆大學生是一張白紙,啥也不會。
不論他在學校學的多好,都沒用,因為他沒練過,不能干活;同理,不論他在學校學的多差,進入工作崗位后,只要肯練,工作也不成問題。
即,剛畢業的學生,只要你做的是工科的軟件開發,不是科學類的理科研發;那么,本質上,大家是不存在優秀與普通的差別的。
為什么要學習Java?
在Web端,Java是毫無疑問的領頭羊;所以,從事Web開發的Net開發者學習一下Java,其實還是很有益處的,取長補短嘛。
而且,在工作中我們難免是要遇到和Java接口對接的情況的;如果你足夠了解Java,那么,對方是否假配合你很快就能發覺了;如果被人搞到離職了,還跟人稱兄道弟的,就有點Low了。
下面,我以IDEA(Java的VisualStudio),創建一個Spring項目,重溫一下Java。
Java重溫
首先打開IDEA,點擊File-New-Project(我手上只有英文版IDEA);如下圖:
在NewProject界面里,選擇Spring Intinalizr,然后勾選Default,點擊Next;
然后我們會經歷一個【等待界面】,該界面是用來下載Spring模板的;這是因為Spring的模板不在IDEA中集成,所以創建時,需要在網上下載。
由於VisualStudio集成了大量模板,所以,我們幾乎不用自己去找模板下載;如果情況特殊,我們需要找模板的話,那也是到網站上下載,然后手動安裝。比如MVC2的時代,你想用MVC3的模板。
所以,對於Net開發而言,這種IDE提供下載模板渠道的模式,我們還是比較陌生的。不過IDEA也提供手動安裝模板的功能,勾選Custom就可以使用手動安裝模式了。
【等待界面】結束后,進入下圖界面:
這個界面里有兩個參數需要設置,一個是Group,一個是Artifact。那么這兩個參數的作用是什么呢?
從字面上我是理解不了的,於是我百度了一下。。。然后,呃。。。我還是很混亂。。。
調查后,我大概得出一個結果,就是Group和Artifact是這個項目的唯一標識,Group是組織唯一標識,Artifact是項目唯一標識。
呃。。。我想,對於對於Net開發而言,這應該是很難理解的。項目唯一標識?這是什么鬼?唯一標識這個詞怎么聽起來像主鍵呢。。。項目怎么還需要唯一標識呢。。。
那到底要如何解釋他們呢?
我想,應該是這樣的,Java創建者的初始目的可能是想創建一個地球村共榮圈。。。所以,每一個Java項目都被期待着被共享,如果項目被共享,那么項目就需要唯一標識Artifact。如果一個公司共享了多個項目,那要證明這些項目都從屬於該公司,那就需要組織(公司)唯一標識Group。
換成Net的描述就是,你創建的每一個Net項目都被微軟期待着,共享到Nuget上,所以你創建項目之前,要先創建這個項目在Nuget上的唯一標識。(很顯然微軟沒有這個期待)
這樣,似乎就很好理解Group和Artifact了。
但是,因為現實中,不論Java還是Net都不可能每個項目都共享,所以,當我們做一個非開源項目時,這兩個屬性設置,就有點雞肋了。
----------------------------------------------------------------------------------------------------
下面看一下,我認為這個界面中第三個重要的屬性配置—Package。
可以在圖中看到,系統默認把Package賦值成了Group+Artifact的值了—kibagroup.kibaarifact。
這里的Package大約等於C#里的命名空間。呃。。。然后,這個默認賦值我就覺得很奇葩了。。。
比如,你做了唯一標識,Group等於公司名kibacompany,Artifact等於項目kibatest;然后,你項目的默認命名空間就是kibacompany.kibatest。。。
很顯然,這件事,對我而言很難理解,還好,IDEA支持我們去修改默認Package。
----------------------------------------------------------------------------------------------------
這里我們修改Package為KibaJavaStart。
修改完Package后,我們點擊Next繼續,如下圖:
選擇圖中的Web項目和其子選項中的Spring Web,然后點擊下一步。
如上圖所示,我們創建項目已經到了最后一步了,因為右下角不在是Next,而是Finish了。
在最后的這個界面里,系統提示我們設置ProjectName(項目名稱)。
根據Net的習慣,項目名稱通常和默認命名空間一樣,所以這里我也賦值KibaJavaStart。
點擊Finish,項目創建完成,界面如下:
項目簡介
在上圖中有三個大文件夾,和若干文件。
文件夾
其中前兩個.idea和.mvn分別是IDEA開發工具和Maven管理工具的配置文件、管理文件等等(Maven類似nuget,但它還管理代碼的生成和發布。。。貌似比IEDA還好用。。。這里Net開發就需要轉變一下觀念了,因為Java不是C#一家獨大,所以他的相關工具存在的功能重復的問題,所以Java開發通常都是用組合工具在開發,不像我們一個VisualStudio走天下)
第三個src是我們項目的核心文件,java代碼都在這里;src我猜就是source的意思,不知道為什么它不用全拼。。。
我們可以看到,在展開的src文件夾中,有着一層,兩層,三層。。。呃。。。好多層文件夾。。。誰說的臃腫。。。
呃。。。我們可以看到其中java這個文件夾的顏色是不一樣的,它代表的着,它下面的代碼是核心Java代碼。
與java文件夾同級的resources文件夾,顧名思義,存的是資源文件;不過他這個資源文件幾乎什么都可以存儲,比如圖片,配置字符串,XML數據,SQL查詢語句等等。(可能Net項目很少如此集中的存儲資源,所以感官上可能會有些奇怪,但我覺得java的這種資源集中的做法是很科學的,非常值得Net開發借鑒學習)
----------------------------------------------------------------------------------------------------
文件
在剩下的若干文件中,我們暫時只關注Pom.xml文件;它是Java的配置文件,不過他並不類似於Net的App.config,他相對的更接近Net的.csproj工程文件,里面存儲引用了那些Jar包(Net里就是dll)。
Java的Web是有類似於Net的App.config文件的文件的,他叫做web.xml,不過,很明顯,我們在這里看不到,我們暫時不關注他,后文會講到它。
Java里還有個數據配置文件,在這里配置的信息可以在Java代碼里被訪問;他就是java的數據配置文件在resources文件夾下的application.properties(類似App.config的AppSettings使用configSource把配置文件外放)如下圖:
Web項目開發
首先,我們找到我們的默認命名空間,Java里的默認包—KibaJavaStart,如下圖:
可以看到,在KibaJavaStart包下只有一個類ArtifactApplication,類里只有一個方法Main。
Main方法?不是Web項目嗎?怎么還有Main方法?
如果你這么想,那一定是你Low了,嘿嘿;學一下Asp.Net Core吧,我們的Core也有Main函數了。
學習了Asp.Net Core我們就了解了,這個承載Main函數的Application類,就是Asp.Net Core的Program類。
吐槽一下
1,現在項目創建完成后,系統在生成一個Main函數啟動類時,使用了Arifact的值來做開頭;這事很奇怪,Arifact是和Group在第一步一起創建的,兩者是上下級關系;但現在Arifact又突然的和最后一步創建默認包名成了上下級關系,這感覺太詭異了,為什么不直接用Application命名呢,非要這樣結合一下呢?
2,項目創建完成后自帶的項目文件也太少了吧,就一個Main函數啟動類,這讓人怎么自學啊,逼着我們去看教程啊。
----------------------------------------------------------------------------------------------------
言歸正傳,一起看代碼。。。
首先第一行代碼,聲明包名稱。
package KibaJavaStart;
意義很簡單,就是聲明類所在的包名;不過,這里與C#不同的是,這個包名是固定的,不可修改的。
也就是說,這個類文件在文件夾KibaJavaStart下,他的包名就必須是KibaJavaStart;如果是在文件夾KibaJavaStart/Test下,他的包名就必須是KibaJavaStart.Test。
是的,這的確很不方便,不過,我們換一個角度考慮,Java文件夾的設置已經很臃腫了,剛剛創建就來了好幾層,如果不強制包名稱和文件夾名一致,那只怕會帶來更多的不便。
我們接着看代碼。
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
聲明包名后,引入兩個Spring包,理由很簡單,因為Main函數要使用這兩個包里的內容。
這里import與C#里的Using引用命名空間的用法類似。
因為創建的是Spring項目,所以一些相關的Spring的Jar依賴(類似C#的Dll)已經被默認引用進來了,可以在項目的External Libraries下找到相關引用;如下圖:
我們知道在C#項目中,被引用的DLL會被復制一份到本地目錄。
不過,在Java項目卻不是這樣的,我們打開項目的所在文件目錄,會發現,目錄里並沒有這些Jar文件。
所以我猜想,被引用的Jar還在原來的位置,只有被編譯的時候才會被調用。
----------------------------------------------------------------------------------------------------
在Java里,JDK自帶的Jar包相對比Net而言,還是較少的,所以,在開發Java時,通常要引用很多很多個Jar包。
比如Spring框架就不在JDK自帶的Jar包里,所以,使用Spring框架開發項目,就要先下載其相應的Jar包。
因為,我們是使用IDEA開發工具開發,而IDEA默認的下載Jar包的工具是Maven,那么下載的Jar包自然是由Maven管理;即,它們應該在Maven工具的所在目錄下。
Maven管理工具好像是沒有界面的,只能用命令行來操作;不過IDEA為我們提供了操作Maven的界面,現在我們打開IDEA提供的Maven操作界面。
File—Settings—Build,Execution,Deployment—BuildTools—Maven,如下圖:
可以看到Maven不僅支持下載Jar包,還支持自定義保存下載Jar包的位置。
圖中的Local repository就是保存已下載Jar包的位置了。
----------------------------------------------------------------------------------------------------
回到代碼。
@SpringBootApplication
這種@開頭的東西叫注解,它使用方式與C#的特性類似,要放在類,函數,屬性上面;然后在注解(特性)的定義里去找到它的宿主(類or函數or屬性),然后為他增加特性;當然,也可設置成只支持類或者只支持函數的模式。
不過Java里的注解實在是太多了、太強大了、太復雜了;注解不僅擁有各種各樣的功能,還互相依賴,甚至注解和注解之間還有嵌套;目前Java已經發展到了不使用注解,開發就舉步維艱的地步了。
有些注解在Net開發看來,真的有些奇葩,比如這個@Data注解,你都想象不到他是干什么的。
如上圖所示,我們定義了一個實體類DataTest ;類里定義兩個私有字段,然后我們在類的頭上加了一個Data注解,然后。。。然后。。。
然后,這個Data注解就會自動給這兩個私有字段變成屬性。。。
也許是因為我定義實體時總是想着他要被充血,所以我才覺得這注解很奇葩吧。。。
在上圖中我們還可以看到,@Data注解是紅色的,這是因為,我們還沒有引入他依賴的Jar包。如何引用呢?呃。。。目前我只知道一種方法。。。
打開pom.xml,找到dependencies標簽,在他的下面添加@Data依賴的Jar包 (手敲的),如下圖:
圖中除了@Data的依賴的lombok包,還有兩個依賴,一個是spring-boot-starter,一個是spring-boot-starter-web;簡單介紹下,這兩個依賴是Spring框架的基礎依賴,如果創建項目時未幫我們自動添加這倆依賴,則需要我們手動添加一下,不然會影響項目運行。
PS:在dependency標簽中,我們會發現,他的子標簽是groupId和artifactId,而spring-boot-starter包和spring-boot-starter-web包的groupId又是一樣的,結合我們上文創建項目時設置Group和Artifact,可以想到,spring-boot-starter包和spring-boot-starter-web包都是由org.springframework.boot組織創建的開源項目,而我們在項目中,引用這種開源項目時,需要在dependency標簽下增加groupId和artifactId兩個標簽,並在其中填寫這個項目創建時設置的Group和Artifact屬性值。
----------------------------------------------------------------------------------------------------
在Java的工程文件里添加完依賴后,我們所依賴的Jar並不會被下載,還需要手動使用Maven來下載,(這個下載依賴庫的方式有點倒序的意思和Net不一樣)順序如下。
1,點擊左下角快捷圖標,打開Maven管理工具,如下圖:
點擊后,右側會彈出Maven管理工具,如下圖:
點擊圖中紅框內的下載按鈕,然后彈出浮動窗,在浮動窗內點擊第一項Download Source,如下圖:
然后IDEA下方會出現一個下載進度條,雙擊進度條可以最大化,里面有詳細信息(如果網速很快或者Jar包很小,該進度條可能一閃而過),如下圖:
最后我們回到實體類,將鼠標放到@Data上,點擊Alt+Enter,然后在彈出的浮動窗上點擊Import class,然后系統會為我們引入@Data注解所屬的Jar包—import lombok.Data;。
現在@Data注解就可以正常運行了,不過,這個過程好像有點。。。
----------------------------------------------------------------------------------------------------
回到注解@SpringBootApplication。。。
注解@SpringBootApplication是一個組合注解,包含@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan。
@SpringBootConfiguration:將當前類標記為配置類。上文我提到了Java項目里有個web.xml配置文件(類似app.config),不過創建項目時並沒有自動生成;其原因就是這個注解了。
Spring框架項目編譯時會檢測這個注解(組合注解@SpringBootApplication也會被檢測),檢測到后會把這個類下的函數,全部提取出來,然后在逐個處理; 怎么處理呢?我猜,是通過反射找到函數的函數名,參數,然后執行一下得到返回值;然后把這些字符串組成復合規則的Xml標簽,再寫進web.xml配置文件。
這樣做的好處就是繁瑣的XML文件配置,被轉化成了代碼編寫,而且java項目的web.xml最終好像是會被編譯進jar,所以這種動態生成web.xml的模式好想也沒什么問題。
@EnableAutoConfiguration,@ComponentScan簡單理解就是使其他注解生效,如@Controller等;換言之,是使其他注解狀態為Enable和為其他注解提供配置信息的注解。
即該注解是其他注解的依賴。。。。。。
----------------------------------------------------------------------------------------------------
我們接着看代碼,現在到了類的主體代碼了,代碼如下:
public class ArtifactApplication { public static void main(String[] args) { SpringApplication.run(ArtifactApplication.class, args); } }
可以看到,該類是一個擁有Main函數的入口類,類里Main函數主要實現一個功能調用SpringApplication命名空間下的靜態方法Run。
我猜測,該方法的主要功能和AspNetCore的 WebHost.CreateDefaultBuilder(args).UseStartup<Startup>().Build();這句話是一個意思,都是啟動一個服務器進程。
服務進程啟動以后,就可以把我們的Web搭建進去了,我們可以看到Run函數第一個參數就要求主類的類名,這代表服務器啟動后,會通過這個入參來啟動Web項目。
這里Srping和Core的區別就是Spring啟動的服務器是Tomcat,而Core啟動的服務器是Kestrel。
創建一個Api
現在Java項目我們已經創建完了,該了解的基礎我們也了解了,那么讓我們一起創建一個Api,然后運行一下看看效果吧。
首先我們創建一個ApiController的文件夾,然后添加一個HelloController文件,然后編寫代碼如下:
@RestController public class HelloController { @RequestMapping(value = "/GetName", method = RequestMethod.GET) public String GetName() { return "我是Kiba518"; } @RequestMapping(value = "/GetAge", method = RequestMethod.GET) public int GetAge() { return 518; } }
可以看到,代碼中在類的上面加了一個注解@RestController,該注解表示當前類是一個遵循REST風格的Api類;類似於Net里的Controller繼承ApiController。
接着我們創建了兩個函數GetName和GetAge;他們的頭上使用@RequestMapping注解,該注解的作用是設置訪問該函數的地址。
即,函數GetName和GetAge的訪問地址為 http://127.0.0.1:8010/GetName和 http://127.0.0.1:8010/GetAge;訪問時,我們需要注意,GetName和GetAge這個地址是區分大小寫的。。。
現在Shift+F10運行下項目,測試一下我們的WebApi。
如上圖,WebApi訪問成功。不過我們訪問的端口是8010。
還記得上面說的Spring啟動時會創建一個服務器嗎,這個端口就是服務器監聽的端口。
當然了,這個端口是可配置的,配置的位置就在application.properties里。
不過.properties文件編寫和閱讀不太方便,我們把他改為.yml,然后修改代碼如下:
server: port: 8010
這個配置文件里的內容是可以被Java訪問的,而且Spring框架項目編譯時也會先讀這里的內容,找到同名的配置,就會替換默認的配置。
PS:Java中控制訪問地址的注解非常多,控制地址訪問的模式也非常多,多到有點誇張的地步。。。
結語
從開發工具的角度來看,Java的開發工具的使用相較Net而言,是比較怪異的,因為,它有一些工具的設計和使用是倒序的。
而Java工具又比較多,因此,這種正序工具和倒序工具同時存在同時使用,感覺上就有一點怪,不過習慣了以后倒也沒什么。
從開發的角度來看,Java的主流Spring和Net幾乎沒有什么區別,唯一的區別就是Java使用注解而Net使用繼承。
----------------------------------------------------------------------------------------------------
代碼已經傳到Github上了,歡迎大家下載。
Github地址:https://github.com/kiba518/KibaJavaStart
----------------------------------------------------------------------------------------------------
注:此文章為原創,任何形式的轉載都請聯系作者獲得授權並注明出處!
若您覺得這篇文章還不錯,請點擊下方的【推薦】,非常感謝!
https://www.cnblogs.com/kiba/p/12052925.html