@Autowired註解能夠高效的幫助我們實現依賴注入,當然,前提是存在對應的bean已經添加進我們的ioc容器中。
我們從一個簡易的Controller類着手,順便回憶一下springMVC的部分知識。
在我的AccountController
類中,類名標註了@Controller
,說明該類會以控制器組件,加入到容器中,類和方法上都有@RequestMapping
註解,那麼我就可以通過/account/findAll
和/account/saveAccount
請求路徑來響應對應的請求。此處忽略了springMVC的相關配置信息,不清楚的可以查看之前的內容。很明顯,這裏的findAll方法,我們是想模擬查詢所有賬戶信息的請求,Controller需要對應Service組件,Service又需要對應的Dao組件。傳統方式下,我們需要自己new一個對象出來,而spring非常高效的幫助我們完成了這一任務,而且完成的非常優雅。
@Controller
@RequestMapping("/account")
public class AccountController {
@Autowired
private AccountService accountService;
@RequestMapping("/findAll")
public String findAll(Model model){
System.out.println("表現層:查詢所有賬戶 findAll...");
List<Account> accounts = accountService.findAll();
model.addAttribute("accountList",accounts);
return "account";
}
@RequestMapping("/saveAccount")
public void saveAccount(Account account, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("表現層:保存當前賬戶 saveAccount...");
accountService.saveAccount(account);
request.getRequestDispatcher("findAll").forward(request,response);
}
}
不難想象,我的AccountService
類上肯定是標註了@Service
註解的,只要spring配置了對應的包掃描,那麼web服務在啓動後,會將標註有@Service
、@Repository
、@Component
註解的類,都加入到ioc容器中,默認索引名爲對應類的首字母小寫。這裏沒有提到@Controller
,該註解的所有類,一般交給springMVC處理。配置包掃描時多配置一個include
或exclude
可以實現對應的包含或忽略。
掃描所有組件後,還會注入對應組件的相關依賴。例如這裏的AccountController
組件中,有AccountService
相關的依賴,就需要在後者加入到ioc容器中,繼而注入對應依賴的引用。
①先根據類型進行查找,查找ioc容器中是否有類型爲AccountService的組件,如果存在多個(相關的 接口/類 被 實現/繼承),則需要繼續根據對應的變量名繼續查找。如果我的容器中,只有一個AccountService類型的組件,那麼根據類型查找即可完成依賴注入。
②如果同一類型存在多個,則繼續通過變量名的方式繼續查找。前面提到了,默認的索引名爲對應類的首字母小寫格式。AccountService在容器中存的名字記爲accountService,如果有一個擴展的類,繼承自AccountService,它的類名爲AccountServiceExt,則它在容器中的名字爲accountServiceExt。
③這裏的private AccountService accountService
變量名,我剛好取的和容器中的名字一樣,如果我簡化成了as,那當容器中存在多個同類型的組件時,是無法找到唯一鎖定的組件注入的,這是我們可以在該屬性的上方添加 @Qualifier("accountService")
註解,這樣可以保證在根據變量名查找的時候,用accountService。
④如果不嚴格要求對應屬性必須被注入,比如這裏的accountService我可以讓它爲null,那麼需要設置 @Autowired(required = false)
,這裏需要注意的是,required的默認只爲true,表示當標註了@Autowired在注入時沒有查到唯一對應的組件時,系統報錯;另一個需要注意的是required爲該註解的一個屬性,不要單獨拿出來再當一個註解用,會報錯的。