Spring?@bean和@component注解區(qū)別
本文打算介紹幾個不太容易說出其區(qū)別,或者用途的 Spring 注解,比如 @Component 與 @Bean 的比較,@ControllerAdvice 是如何處理自定義異常的等等。
Spring 中的一些注解
1. @Component 和 @Bean 的區(qū)別是什么?
作用對象不同:@Component 注解作用于類,而 @Bean 注解作用于方法、
@Component 通常是通過路徑掃描來自動偵測以及自動裝配到 Spring 容器中(我們可以使用 @ComponentScan 注解定義要掃描的路徑從中找出標(biāo)識了需要裝配的類自動裝配到 Spring 的 bean 容器中)。@Bean 注解通常是我們在標(biāo)有該注解的方法中定義產(chǎn)生這個 bean,@Bean 告訴了 Spring 這是某個類的實例,當(dāng)我們需要用它的時候還給我。
@Bean 注解比 @Component 注解的自定義性更強(qiáng),而且很多地方我們只能通過 @Bean 注解來注冊 bean。比如當(dāng)我們引用第三方庫中的類需要裝配到 Spring 容器時,只能通過 @Bean 來實現(xiàn)。
@Bean 注解使用示例:
@Configuration public class AppConfig { @Bean public TransferService transferService() { return new TransferServiceImpl(); } }
@Component 注解使用示例:
@Component public class ServiceImpl implements AService { .... }
下面這個例子是通過 @Component 無法實現(xiàn)的:
@Bean public OneService getService(status) { case (status) { when 1: return new serviceImpl1(); when 2: return new serviceImpl2(); when 3: return new serviceImpl3(); } }
2. Autowire 和 @Resource 的區(qū)別
@Autowire 和 @Resource都可以用來裝配bean,都可以用于字段或setter方法。Spring Boot 學(xué)習(xí)筆記分享給你。
@Autowire 默認(rèn)按類型裝配,默認(rèn)情況下必須要求依賴對象必須存在,如果要允許 null 值,可以設(shè)置它的 required 屬性為 false。
@Resource 默認(rèn)按名稱裝配,當(dāng)找不到與名稱匹配的 bean 時才按照類型進(jìn)行裝配。名稱可以通過 name 屬性指定,如果沒有指定 name 屬性,當(dāng)注解寫在字段上時,默認(rèn)取字段名,當(dāng)注解寫在 setter 方法上時,默認(rèn)取屬性名進(jìn)行裝配。
注意:如果 name 屬性一旦指定,就只會按照名稱進(jìn)行裝配。
@Autowire和@Qualifier配合使用效果和@Resource一樣:
@Autowired(required = false) @Qualifier("example") private Example example; @Resource(name = "example") private Example example;
@Resource 裝配順序
- 如果同時指定 name 和 type,則從容器中查找唯一匹配的 bean 裝配,找不到則拋出異常;
- 如果指定 name 屬性,則從容器中查找名稱匹配的 bean 裝配,找不到則拋出異常;
- 如果指定 type 屬性,則從容器中查找類型唯一匹配的 bean 裝配,找不到或者找到多個拋出異常;
- 如果不指定,則自動按照 byName 方式裝配,如果沒有匹配,則回退一個原始類型進(jìn)行匹配,如果匹配則自動裝配。
3. 將一個類聲明為 Spring 的 bean 的注解有哪些?
- @Component :通用的注解,可標(biāo)注任意類為 Spring 的組件。如果一個 Bean 不知道屬于哪個層,可以使用 @Component 注解標(biāo)注。
- @Repository :對應(yīng)持久層即 Dao 層,主要用于數(shù)據(jù)庫相關(guān)操作。
- @Service :對應(yīng)服務(wù)層,主要設(shè)計一些復(fù)雜的邏輯,需要用到 Dao 層。
- @Controller :對應(yīng) Spring MVC 控制層,主要用來接受用戶請求并調(diào)用 Service 層返回數(shù)據(jù)給前端頁面。
- @Configuration :聲明該類為一個配置類,可以在此類中聲明一個或多個 @Bean 方法。
4. @Configuration :配置類注解
@Configuration 表明在一個類里可以聲明一個或多個 @Bean 方法,并且可以由 Spring 容器處理,以便在運(yùn)行時為這些 bean 生成 bean 定義和服務(wù)請求,例如:
@Configuration public class AppConfig { ? ? @Bean public MyBean myBean() { // instantiate, configure and return bean ... ? ? } }
我們可以通過 AnnotationConfigApplicationContext 來注冊 @Configuration 類:
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class); ctx.refresh(); MyBean myBean = ctx.getBean(MyBean.class); // use myBean ...
另外也可以通過組件掃描(component scanning)來加載,@Configuration 使用 @Component 進(jìn)行原注解,因此 @Configuration 類也可以被組件掃描到(特別是使用 XML 的 元素)。@Configuration 類不僅可以使用組件掃描進(jìn)行引導(dǎo),還可以使用 @ComponentScan 注解自行配置組件掃描:
@Configuration @ComponentScan("com.acme.app.services") public class AppConfig { // various @Bean definitions ... }
使用 @Configuration 的約束:
- 配置類必須以類的方式提供(比如不能是由工廠方法返回的實例)。
- 配置類必須是非 final 的。
- 配置類必須是非本地的(即可能不在方法中聲明),native 標(biāo)注的方法。
- 任何嵌套的配置類必須聲明為 static。
- @Bean 方法可能不會反過來創(chuàng)建更多的配置類。
- 除了單獨(dú)使用 @Configuration 注解,我們還可以結(jié)合一些外部的 bean 或者注解共同使用,比如 Environment API,@PropertySource,@Value,@Profile 等等許多,這里就不做詳細(xì)介紹了,更多的用法可以參看 Spring @Configuration 的相關(guān)文檔 。
推薦一個 Spring Boot 基礎(chǔ)教程及實戰(zhàn)示例:https://github.com/javastacks...
5. @ControllerAdvice :處理全局異常利器
在 Spring 3.2 中,新增了 @ControllerAdvice、@RestControllerAdvice、@RestController 注解,可以用于定義 @ExceptionHandler、@InitBinder、@ModelAttribute,并應(yīng)用到所有 @RequestMapping 、@PostMapping、@GetMapping等這些 Controller 層的注解中。
默認(rèn)情況下,@ControllerAdvice 中的方法應(yīng)用于全局所有的 Controller。而使用選擇器 annotations(),basePackageClasses() 和 basePackages() (或其別名value())來定義更小范圍的目標(biāo) Controller 子集。Spring Boot 學(xué)習(xí)筆記分享給你。
如果聲明了多個選擇器,則應(yīng)用 OR 邏輯,這意味著所選的控制器應(yīng)匹配至少一個選擇器。請注意,選擇器檢查是在運(yùn)行時執(zhí)行的,因此添加許多選擇器可能會對性能產(chǎn)生負(fù)面影響并增加復(fù)雜性。
@ControllerAdvice 我們最常使用的是結(jié)合 @ExceptionHandler 用于全局異常的處理??梢越Y(jié)合以下例子,我們可以捕獲自定義的異常進(jìn)行處理,并且可以自定義狀態(tài)碼返回:
@ControllerAdvice("com.developlee.errorhandle") public class MyExceptionHandler { /** * 捕獲CustomException * @param e * @return json格式類型 */ @ResponseBody @ExceptionHandler({CustomException.class}) //指定攔截異常的類型 @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) //自定義瀏覽器返回狀態(tài)碼 public Map>String, Object< customExceptionHandler(CustomException e) { Map<String, Object> map = new HashMap<>(); map.put("code", e.getCode()); map.put("msg", e.getMsg()); return map; } }
更多信息可以參看 Spring @ControllerAdvice 的官方文檔。推薦一個 Spring Boot 基礎(chǔ)教程及實戰(zhàn)示例:https://github.com/javastacks/spring-boot-best-practice
6. @Component, @Repository, @Service 的區(qū)別
@Component是一個通用的Spring容器管理的單例bean組件。而@Repository, @Service, @Controller就是針對不同的使用場景所采取的特定功能化的注解組件。
因此,當(dāng)你的一個類被@Component所注解,那么就意味著同樣可以用@Repository, @Service, @Controller 來替代它,同時這些注解會具備有更多的功能,而且功能各異。
最后,如果你不知道要在項目的業(yè)務(wù)層采用@Service還是@Component注解。那么,@Service是一個更好的選擇。
總結(jié)
以上簡單介紹了幾種 Spring 中的幾個注解及代碼示例,就我個人而言,均是平時用到且不容易理解的幾個,或者容易忽略的幾個。當(dāng)然,這篇文章并沒有完全介紹完,在今后還會繼續(xù)補(bǔ)充完善。
到此這篇關(guān)于Spring @bean和@component注解區(qū)別的文章就介紹到這了,更多相關(guān)Spring @bean @component內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot項目導(dǎo)入aliyun oss starter依賴后啟動報錯問題
這篇文章主要介紹了SpringBoot項目導(dǎo)入aliyun oss starter依賴后啟動報錯問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01Springboot實現(xiàn)ENC加密的詳細(xì)流程
在項目開發(fā)過程中,需要配置數(shù)據(jù)庫連接密碼、Redis密碼、網(wǎng)盤上傳的AK/SK等敏感信息,都需要保存在配置文件里,或者配置中心,這些信息如果泄露,還是會造成一定的困擾,下面這篇文章主要給大家介紹了關(guān)于Springboot實現(xiàn)ENC加密的詳細(xì)流程,需要的朋友可以參考下2023-06-06