序言
@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: 數據持久層註解,通常承擔向數據庫讀寫數據的任務。
最後,我們可以通過一張圖進一步瞭解這四個註解的區別和聯繫:
簡單來說,@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>
本文所涉及到的源碼,你可以點擊下方的按鈕進行下載:
閱讀更多 ramostear 的文章