Spring 注解比較,@Bean 和 @Component的區(qū)別
閱讀本文大概需要 5 分鐘。
來自:blog.csdn.net/weixin_35544490/article/details/112143211
本文打算介紹幾個不太容易說出其區(qū)別,或者用途的 Spring 注解,比如 @Component 與 @Bean 的比較,@ControllerAdvice 是如何處理自定義異常的等等。
Spring 中的一些注解
1. @Component 和 @Bean 的區(qū)別是什么?
作用對象不同: @Component注解作用于類,而@Bean注解作用于方法、@Component通常是通過路徑掃描來自動偵測以及自動裝配到 Spring 容器中(我們可以使用@ComponentScan注解定義要掃描的路徑從中找出標識了需要裝配的類自動裝配到 Spring 的 bean 容器中)。@Bean注解通常是我們在標有該注解的方法中定義產生這個 bean,@Bean告訴了 Spring 這是某個類的實例,當我們需要用它的時候還給我。@Bean注解比@Component注解的自定義性更強,而且很多地方我們只能通過@Bean注解來注冊 bean。比如當我們引用第三方庫中的類需要裝配到 Spring 容器時,只能通過@Bean來實現(xiàn)。
@Bean 注解使用示例:@Configuration
public class AppConfig {
@Bean
public TransferService transferService() {
return new TransferServiceImpl();
}
}
@Component
public class ServiceImpl implements AService {
....
}
@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方法。@Autowire默認按類型裝配,默認情況下必須要求依賴對象必須存在,如果要允許 null 值,可以設置它的 required 屬性為 false。@Resource默認按名稱裝配,當找不到與名稱匹配的 bean 時才按照類型進行裝配。名稱可以通過 name 屬性指定,如果沒有指定 name 屬性,當注解寫在字段上時,默認取字段名,當注解寫在 setter 方法上時,默認取屬性名進行裝配。
注意:如果 name 屬性一旦指定,就只會按照名稱進行裝配。
@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 方式裝配,如果沒有匹配,則回退一個原始類型進行匹配,如果匹配則自動裝配。
3. 將一個類聲明為 Spring 的 bean 的注解有哪些?
@Component:通用的注解,可標注任意類為 Spring 的組件。如果一個 Bean 不知道屬于哪個層,可以使用@Component注解標注。@Repository:對應持久層即 Dao 層,主要用于數據庫相關操作。@Service:對應服務層,主要設計一些復雜的邏輯,需要用到 Dao 層。@Controller:對應 Spring MVC 控制層,主要用來接受用戶請求并調用 Service 層返回數據給前端頁面。@Configuration:聲明該類為一個配置類,可以在此類中聲明一個或多個@Bean方法。
4. @Configuration :配置類注解
@Configuration 表明在一個類里可以聲明一個或多個 @Bean 方法,并且可以由 Spring 容器處理,以便在運行時為這些 bean 生成 bean 定義和服務請求,例如:@Configuration
public class AppConfig {
@Bean
public MyBean myBean() {
// instantiate, configure and return bean ...
}
}
@Configuration 類:AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.refresh();
MyBean myBean = ctx.getBean(MyBean.class);
// use myBean ...
@Configuration 使用 @Component 進行原注解,因此 @Configuration 類也可以被組件掃描到(特別是使用 XML 的 元素)。@Configuration 類不僅可以使用組件掃描進行引導,還可以使用 @ComponentScan 注解自行配置組件掃描:@Configuration
@ComponentScan("com.acme.app.services")
public class AppConfig {
// various @Bean definitions ...
}
配置類必須以類的方式提供(比如不能是由工廠方法返回的實例)。 配置類必須是非 final 的。 配置類必須是非本地的(即可能不在方法中聲明),native 標注的方法。 任何嵌套的配置類必須聲明為 static。 @Bean 方法可能不會反過來創(chuàng)建更多的配置類。
@Configuration 注解,我們還可以結合一些外部的 bean 或者注解共同使用,比如 Environment API,@PropertySource,@Value,@Profile 等等許多,這里就不做詳細介紹了,更多的用法可以參看 Spring @Configuration 的相關文檔 。5. @ControllerAdvice :處理全局異常利器
@ControllerAdvice、@RestControllerAdvice、@RestController 注解,可以用于定義 @ExceptionHandler、@InitBinder、@ModelAttribute,并應用到所有 @RequestMapping 、@PostMapping、@GetMapping等這些 Controller 層的注解中。@ControllerAdvice 中的方法應用于全局所有的 Controller。而使用選擇器 annotations(),basePackageClasses() 和 basePackages() (或其別名value())來定義更小范圍的目標 Controller 子集。如果聲明了多個選擇器,則應用 OR 邏輯,這意味著所選的控制器應匹配至少一個選擇器。請注意,選擇器檢查是在運行時執(zhí)行的,因此添加許多選擇器可能會對性能產生負面影響并增加復雜性。@ControllerAdvice 我們最常使用的是結合 @ExceptionHandler 用于全局異常的處理。可以結合以下例子,我們可以捕獲自定義的異常進行處理,并且可以自定義狀態(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;
}
}
6. @Component, @Repository, @Service 的區(qū)別

@Component是一個通用的Spring容器管理的單例bean組件。而@Repository, @Service, @Controller就是針對不同的使用場景所采取的特定功能化的注解組件。@Repository, @Service, @Controller 來替代它,同時這些注解會具備有更多的功能,而且功能各異。@Service還是@Component注解。那么,@Service是一個更好的選擇。總結
推薦閱讀:
一女程序員被判 9 個月:因薪酬等問題離職,rm -f * 刪庫,癱瘓 6 個小時
最近面試BAT,整理一份面試資料《Java面試BATJ通關手冊》,覆蓋了Java核心技術、JVM、Java并發(fā)、SSM、微服務、數據庫、數據結構等等。
朕已閱 
評論
圖片
表情

