目錄
1. 創建測試項目
2. 改變啟動類所屬包?
3. 使用@ComponentScan
4. Spring基本掃描機制
程序通過注解告訴Spring希望哪些bean被管理,但在僅使用@Bean時已經發現,Spring需要根據五大類注解才能進一步掃描方法注解。
由此可見,Spring對注解的掃描并不是全項目掃描的,本文對Spring的基本掃描機制進行驗證。
1. 創建測試項目
創建項目及Controller包、Service包、Repo包、Component包、Config包,目錄結構如下:
本例測試與Controller包下的UserController類 和 Service包下的UserService類相關,
UserController類內容如下:
package com.example.iocdemo1.Controller;import org.springframework.stereotype.Controller;@Controller
public class UserController {public void doController(){System.out.println("do Controller...");}
}
UserService類內容如下:
package com.example.iocdemo1.Service;import org.springframework.stereotype.Service;@Service
public class UserService {public void doService(){System.out.println("doService...");}
}
啟動類內容如下:
package com.example.iocdemo1.Controller;import com.example.iocdemo1.Service.UserService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;@SpringBootApplication
public class IoCDemo1Application {public static void main(String[] args) {ApplicationContext context=SpringApplication.run(IoCDemo1Application.class, args);UserController controller = context.getBean(UserController.class);controller.doController();UserService userService1=context.getBean(UserService.class);userService1.doService();}
}
2. 改變啟動類所屬包?
現將啟動類移至項目包的其他子包下,以Controller包為例:
基于其他目錄結構及類代碼不變,重新啟動程序,報錯如下:
表示UserService.class這個bean沒有找到(類型為UserController.class的bean獲取成功,并未報錯)。
在SpringBoot中有一個特點:約定大于配置。由于原始Spring項目大量的配置文件造成的不便,SpringBoot做了相關約定以簡化配置。
Spring約定,從啟動類所在的目錄及其子孫目錄開始掃描,
觀察啟動類首行,可見移動啟動類位置后,移動類所屬包:
package com.example.iocdemo1.Controller;
故而Spring默認只掃描該目錄下的包及子包,可掃描到UserController,但掃描不到UserService;
3. 使用@ComponentScan
在當前啟動類前增加@ComponentScan注解以指定掃描目錄路徑,當前若希望掃描到其他的Service包、Repo包、Component包、Config包,則需對應的路徑為com.example.iocdemo1,增加注解后的啟動類內容如下:
package com.example.iocdemo1.Controller;import com.example.iocdemo1.Service.UserService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;@ComponentScan("com.example.iocdemo1")
@SpringBootApplication
public class IoCDemo1Application {public static void main(String[] args) {ApplicationContext context=SpringApplication.run(IoCDemo1Application.class, args);UserController controller = context.getBean(UserController.class);controller.doController();UserService userService1=context.getBean(UserService.class);userService1.doService();}
}
重新啟動程序:
4. Spring基本掃描機制
1、根據上例,可得出Spring對注解的掃描約定如下:
默認掃描路徑為啟動類所在的目錄及其子孫目錄,可通過@ComponentScan注解指定掃描路徑。
2、在項目默認配置中,并沒有手動使用@ComponentScan指定掃描路徑,默認掃描路徑是通過啟動類的@SpringBootApplication注解實現的,Alt+左點擊查看注解聲明:
可見@SpringBootApplication注解當中包含@ComponentScan注解。