Spring 中的一些註解

這是我參與更文挑戰的第6天,活動詳情查看:更文挑戰html

1. @Component@Bean 的區別是什麼?

  1. 做用對象不一樣:@Component 註解做用於類,而 @Bean 註解做用於方法、
  2. @Component 一般是經過路徑掃描來自動偵測以及自動裝配到 Spring 容器中(咱們可使用 @ComponentScan 註解定義要掃描的路徑從中找出標識了須要裝配的類自動裝配到 Springbean 容器中)。@Bean 註解一般是咱們在標有該註解的方法中定義產生這個 bean@Bean 告訴了 Spring 這是某個類的實例,當咱們須要用它的時候還給我。
  3. @Bean 註解比 @Component 註解的自定義性更強,並且不少地方咱們只能經過 @Bean 註解來註冊 bean。好比當咱們引用第三方庫中的類須要裝配到 Spring 容器時,只能經過 @Bean 來實現。

@Bean 註解使用示例:前端

@Configuration
public class AppConfig {
    @Bean
    public TransferService transferService() {
        return new TransferServiceImpl();
    }
}
複製代碼

@Component 註解使用示例:java

@Component
public class ServiceImpl implements AService {
    ....
} 
複製代碼

下面這個例子是經過 @Component 沒法實現的:web

@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 的區別

  1. @Autowire@Resource均可以用來裝配bean,均可以用於字段或setter方法。
  2. @Autowire 默認按類型裝配,默認狀況下必需要求依賴對象必須存在,若是要容許 null 值,能夠設置它的 required 屬性爲 false。
  3. @Resource 默認按名稱裝配,當找不到與名稱匹配的 bean 時才按照類型進行裝配。名稱能夠經過 name 屬性指定,若是沒有指定 name 屬性,當註解寫在字段上時,默認取字段名,當註解寫在 setter 方法上時,默認取屬性名進行裝配。

注意:若是 name 屬性一旦指定,就只會按照名稱進行裝配。面試

  • @Autowire@Qualifier配合使用效果和@Resource同樣:spring

    @Autowired(required = false) @Qualifier("example")
    private Example example;
    
    @Resource(name = "example")
    private Example example;
    複製代碼
  • @Resource 裝配順序數據庫

  1. 若是同時指定 name 和 type,則從容器中查找惟一匹配的 bean 裝配,找不到則拋出異常;
  2. 若是指定 name 屬性,則從容器中查找名稱匹配的 bean 裝配,找不到則拋出異常;
  3. 若是指定 type 屬性,則從容器中查找類型惟一匹配的 bean 裝配,找不到或者找到多個拋出異常;
  4. 若是不指定,則自動按照 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 定義和服務請求,例如:json

@Configuration
public class AppConfig {

    @Bean
    public MyBean myBean() {
        // instantiate, configure and return bean ...
    }
}
複製代碼

咱們能夠經過 AnnotationConfigApplicationContext 來註冊 @Configuration 類:api

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.refresh();
MyBean myBean = ctx.getBean(MyBean.class);
// use myBean ...
複製代碼

另外也能夠經過組件掃描(component scanning)來加載,@Configuration 使用 @Component 進行原註解,所以 @Configuration 類也能夠被組件掃描到(特別是使用 XML 的 <context:component-scan /> 元素)。@Configuration 類不只可使用組件掃描進行引導,還可使用 @ComponentScan 註解自行配置組件掃描:瀏覽器

@Configuration
@ComponentScan("com.acme.app.services")
public class AppConfig {
    // various @Bean definitions ...
}
複製代碼

使用 @Configuration 的約束:

  • 配置類必須以類的方式提供(好比不能是由工廠方法返回的實例)。
  • 配置類必須是非 final 的。
  • 配置類必須是非本地的(便可能不在方法中聲明),native 標註的方法。
  • 任何嵌套的配置類必須聲明爲 static
  • @Bean 方法可能不會反過來建立更多的配置類。

除了單獨使用 @Configuration 註解,咱們還能夠結合一些外部的 bean 或者註解共同使用,好比 Environment API,@PropertySource@Value@Profile 等等許多,這裏就不作詳細介紹了,更多的用法能夠參看 Spring @Configuration 的相關文檔

5. @ControllerAdvice :處理全局異常利器

在 Spring 3.2 中,新增了 @ControllerAdvice@RestControllerAdvice@RestController 註解,能夠用於定義 @ExceptionHandler@InitBinder@ModelAttribute,並應用到全部 @RequestMapping@PostMapping@GetMapping等這些 Controller 層的註解中。

默認狀況下,@ControllerAdvice 中的方法應用於全局全部的 Controller。而使用選擇器 annotations()basePackageClasses()basePackages() (或其別名value())來定義更小範圍的目標 Controller 子集。 若是聲明瞭多個選擇器,則應用 OR 邏輯,這意味着所選的控制器應匹配至少一個選擇器。 請注意,選擇器檢查是在運行時執行的,所以添加許多選擇器可能會對性能產生負面影響並增長複雜性。

@ControllerAdvice 咱們最常使用的是結合 @ExceptionHandler 用於全局異常的處理。能夠結合如下例子,咱們能夠捕獲自定義的異常進行處理,而且能夠自定義狀態碼返回:

@ControllerAdvice("com.developlee.errorhandle")
public class MyExceptionHandler {
    /** * 捕獲CustomException * @param e * @return json格式類型 */
    @ResponseBody
    @ExceptionHandler({CustomException.class}) //指定攔截異常的類型
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) //自定義瀏覽器返回狀態碼
    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 的官方文檔

6. @Component, @Repository, @Service 的區別

註解 含義
@Component 最普通的組件,能夠被注入到 Spring 容器進行管理
@Repository 做用於持久層
@Service 做用於業務邏輯層
@Controller 做用於表現層(spring-mvc的註解)

@Component是一個通用的Spring容器管理的單例bean組件。而@Repository, @Service, @Controller就是針對不一樣的使用場景所採起的特定功能化的註解組件。

所以,當你的一個類被@Component所註解,那麼就意味着一樣能夠用@Repository, @Service, @Controller 來替代它,同時這些註解會具有有更多的功能,並且功能各異。

最後,若是你不知道要在項目的業務層採用@Service仍是@Component註解。那麼,@Service是一個更好的選擇。

總結

以上簡單介紹了幾種 Spring 中的幾個註解及代碼示例,就我我的而言,均是平時用到且不容易理解的幾個,或者容易忽略的幾個。固然,這篇文章並無徹底介紹完,在從此還會繼續補充完善。

連接

相關文章
相關標籤/搜索