Spring Boot框架本身并沒(méi)有對(duì)工程結(jié)構(gòu)有特別的要求,但是按照最佳實(shí)踐的工程結(jié)構(gòu)可以幫助我們減少可能會(huì)遇見(jiàn)的坑,尤其是Spring包掃描機(jī)制的存在,如果您使用最佳實(shí)踐的工程結(jié)構(gòu),可以免去不少特殊的配置工作。
典型示例
以下結(jié)構(gòu)是比較推薦的package組織方式:
com
+- example
+- myproject
+- Application.java
|
+- domain
| +- Customer.java
| +- CustomerRepository.java
|
+- service
| +- CustomerService.java
|
+- web
| +- CustomerController.java
|
root package
:com.example.myproject
,所有的類(lèi)和其他package都在root package之下。- 應(yīng)用主類(lèi):
Application.java
,該類(lèi)直接位于root package
下。通常我們會(huì)在應(yīng)用主類(lèi)中做一些框架配置掃描等配置,我們放在root package下可以幫助程序減少手工配置來(lái)加載到我們希望被Spring加載的內(nèi)容 com.example.myproject.domain
包:用于定義實(shí)體映射關(guān)系與數(shù)據(jù)訪問(wèn)相關(guān)的接口和實(shí)現(xiàn)com.example.myproject.service
包:用于編寫(xiě)業(yè)務(wù)邏輯相關(guān)的接口與實(shí)現(xiàn)com.example.myproject.web
:用于編寫(xiě)Web層相關(guān)的實(shí)現(xiàn),比如:Spring MVC的Controller等
上面的結(jié)構(gòu)中,root package
與應(yīng)用主類(lèi)的位置是整個(gè)結(jié)構(gòu)的關(guān)鍵。由于應(yīng)用主類(lèi)在root package
中,所以按照上面的規(guī)則定義的所有其他類(lèi)都處于root package
下的其他子包之后。默認(rèn)情況下,Spring Boot的應(yīng)用主類(lèi)會(huì)自動(dòng)掃描root package
以及所有子包下的所有類(lèi)來(lái)進(jìn)行初始化。
什么意思呢?舉個(gè)例子,假設(shè)我們將com.example.myproject.web
包與上面所述的root package
:com.example.myproject
放在同一級(jí),像下面這樣:
com
+- example
+- myproject
+- Application.java
|
+- domain
| +- Customer.java
| +- CustomerRepository.java
|
+- service
| +- CustomerService.java
|
+- web
| +- CustomerController.java
|
這個(gè)時(shí)候,應(yīng)用主類(lèi)Application.java
在默認(rèn)情況下就無(wú)法掃描到com.example.myproject.web
中的Controller定義,就無(wú)法初始化Controller中定義的接口。
非典型結(jié)構(gòu)下的初始化
那么如果,我們一定要加載非root package
下的內(nèi)容怎么辦呢?
方法一:使用@ComponentScan
注解指定具體的加載包,比如:
@SpringBootApplication
@ComponentScan(basePackages="com.example")
public class Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Bootstrap.class, args);
}
}
這種方法通過(guò)注解直接指定要掃描的包,比較直觀。如果有這樣的需求也是可以用的,但是原則上還是推薦以上面的典型結(jié)構(gòu)來(lái)定義,這樣也可以少寫(xiě)一些注解,代碼更加簡(jiǎn)潔。
方法二:使用@Bean
注解來(lái)初始化,比如:
@SpringBootApplication
public class Bootstrap {
public static void main(String[] args) {
SpringApplication.run(Bootstrap.class, args);
}
@Bean
public CustomerController customerController() {
return new CustomerController();
}
}
這種方法在業(yè)務(wù)開(kāi)發(fā)的時(shí)候并不是特別推薦,更適合用于框架封裝等場(chǎng)景,關(guān)于更多封裝上的技巧,后面我們?cè)谶M(jìn)階教程中詳細(xì)講解。
注:本文轉(zhuǎn)載自“程序猿DD”,如有侵權(quán),請(qǐng)聯(lián)系刪除!