Spring @Component Annotation(每日一解系列)


Spring @Component Annotation(每日一解系列)


序言

@Component是一個類級別的註解,被此註解作用的Java類,將被Spring視為應用程序中的組件。在開啟組件掃描後,被@Component註解的類會被Spring Framework掃描並納入到Spring容器的管理。在默認情況下,@Component所產生的是一個單例模式的普通組件,且組件的名稱為類名(首字母小寫,使用駝峰命名)。


1.組件掃描

在使用@Component註解之前,需要在應用程序中開啟組件掃描,你可以採用基於XML文件的配置方式,也可以使用@ComponentScan註解進行配置(推薦使用該方式進行配置)。例如:

AppConfig.java

<code>@Configuration
@ComponentScan(basePackages = {"com.ramostear.component.annotation.beans"})
public class AppConfig {
}/<code>

接下來,創建一個名為Demo的Java類,並使用@Component進行註解。


2.使用@Component註解

在com.ramostear.component.annotation.beans包中創建Demo.java類,並使用@Component進行註解,內容如下:

Demo.java

<code>@Component
public class Demo {
   private String text;

   public Demo() {
       this.text = "hello world.";
       System.out.println("--- Initializing Demo component and text="+this.text+" ---");
  }
}/<code>

下面,我們通過AnnotationConfigApplicationContext獲得應用上下文,並從上下文中獲取Demo的bean實例。


3.獲取組件

在main()方法中,可以使用AnnotationConfigApplicationContext類加載應用上下文,並獲得相應的bean。代碼如下:

ComponentAnnotationApplication.java

<code>@SpringBootApplication
public class ComponentAnnotationApplication {

   public static void main(String[] args) {
       SpringApplication.run(ComponentAnnotationApplication.class, args);
       AnnotationConfigApplicationContext context =
               new AnnotationConfigApplicationContext(AppConfig.class);

       Demo demo = context.getBean(Demo.class);
       System.out.println("demo text is : "+ demo.getText());
  }

}/<code>

運行main()方法,觀察控制檯輸出。

Output

<code>--- Initializing Demo component and text=hello world. ---
demo text is : hello world./<code>


4.組件命名

在上面的例子中,我們是通過Bean的類型獲得組件的,除此之外,我們還可以對組件進行命名,然後通過名稱來獲取上下文中的bean。代碼如下:

Demo.java

<code>@Component(value = "demoBean")
public class Demo {
  //省略其他...
}/<code>

使用value屬性指定Demo的bean名稱,接下來,在main()中就可以通過beanName獲得Demo的bean實例。

ComponentAnnotationApplication.java

<code>@SpringBootApplication
public class ComponentAnnotationApplication {

   public static void main(String[] args) {
       SpringApplication.run(ComponentAnnotationApplication.class, args);
       AnnotationConfigApplicationContext context =
               new AnnotationConfigApplicationContext(AppConfig.class);


       /*Demo demo = context.getBean(Demo.class);*/
       Demo demo = (Demo)context.getBean("demoBean");
       System.out.println("demo text is : "+ demo.getText());
  }

}/<code>

Output

<code>--- Initializing Demo component and text=hello world. ---
demo text is : hello world./<code>


5.與@Repository,@Service和@Controller的區別和聯繫

首先,@Component,@Repository,@Service和@Controller這四個註解都是用於定義一個被Spring容器所管理的Bean。應用程序啟動時,Spring會根據類路徑去掃描帶有這些註解的類,然後完成依賴注入工作。對於這四個註解,在技術上的核心目的是相同的,都是為了Spring能夠自動掃描和識別這些組件。而它們之間的卻別在於業務上的分類。下面做一下簡單的介紹:

  • @Component : 它是一個通用的註解,可以在整個應用程序中使用,表明只是一個普通的組件;
  • @Controller : 視圖層的註釋,主要是在Spring MVC中使用,用於定義一個視圖控制器;
  • @Service : 在業務邏輯層使用的註解;
  • @Repository: 數據持久層註解,通常承擔向數據庫讀寫數據的任務。


最後,我們可以通過一張圖進一步瞭解這四個註解的區別和聯繫:


Spring @Component Annotation(每日一解系列)


簡單來說,@Controller,@Service和@Repository是@Component的一種特殊情況,從它們的源碼就能一探究竟:

Component.java

<code>@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
   String value() default "";
}/<code>

Controller.java

<code>@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component //@Component註解
public @interface Controller {
   @AliasFor(
       annotation = Component.class
  )
   String value() default "";
}/<code>

Service.java

<code>@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component //@Component註解
public @interface Service {
   @AliasFor(
       annotation = Component.class
  )
   String value() default "";

}/<code>

Repository.java

<code>@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component //@Component註解
public @interface Repository {
   @AliasFor(
       annotation = Component.class
  )
   String value() default "";
}/<code>


本文所涉及到的源碼,你可以點擊下方的按鈕進行下載:


Spring @Component Annotation(每日一解系列)

https://github.com/ramostear/spring-annotations-daily-example




分享到:


相關文章: