2.2、基於註解的DI注入
學習資源:動力節點的2020最新Spring框架教程【IDEA版】-Spring框架從入門到精通
目錄
基於註解的 DI,是指通過 Spring 提供的註解完成容器物件的建立、屬性初始化,而不再需要使用配置檔案宣告建立 bean 了。
註解使用步驟:
- 匯入 maven 依賴 spring-context
- 在實體類加入註解
- 在 spring 配置檔案中,配置元件掃描器,用於指定掃描哪些包下的註解
Spring 常用註解:
- @Component
- @Respotory
- @Service
- @Controller
- @scope
- @Value
- @Autowire
- @Resource
0、準備工作
0.1、匯入 maven 依賴
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.5.RELEASE</version> </dependency>
0.2、建立實體類
0.3、配置元件掃描器
元件掃描器的工作方式:spring 會掃描逼歷 base-package 指定的包及子包中所有的類,找到類中的註解,按照註解的功能建立物件或給屬性賦值。
配置元件掃描器,在配置檔案中加入:
<context:component-scan base-package="com.chen.pojo"/>
指定掃描多個包的方式:
- 使用多次元件掃描器,掃描不同的包
<context:component-scan base-package="com.chen.pojo"/> <context:component-scan base-package="com.chen.domain"/> ......
- 使用分隔符 ; 或 , 分割多個包
<context:component-scan base-package="com.chen.pojo;com.chen.domain;......"/>
- 指定父包
<context:component-scan base-package="com.chen"/>
1、@Component
作用等同於配置檔案中的 <bean> ,用於向容器中建立物件。需要在實體類上使用註解 @Component
,該註解的 value 屬性用於指定該 bean 的 id 值,id 自定義唯一,value 屬性可預設。
使用例項:
- @Component(value="自定義名稱")
@Component(value="student")
public class Student{
}
- @Component("自定義名稱"),推薦使用
@Component(value="student")
public class Student{
}
- @Component(),此時 bean 會使用 spring 提供的預設名稱:類名首字母小寫
@Component()
public class Student{
}
另外, Spring 還提供了 3 個建立物件的註解:
- @Repository:用於對持久層類(DAO 實現類)進行註解
- @Service:用於對業務層類(Service 實現類)進行註解
- @Controller:用於對控制器類(Controller 實現類)進行註解
這三個註解與 @Component 都可以建立物件,但這三個註解還有其他的含義:@Repository 建立持久層物件,持久層物件是可以操作資料庫的;@Service 建立業務層物件,業務層物件可以加入事務功能;@Controller 註解建立的物件可以作為處理器接收使用者的請求。
@Repository、@Service、@Controller 是用於給專案的物件分層的:持久層、業務層、控制層。而當你不確定某一個物件的角色時,可以使用 @Component 。
2、@Value
功能等同於 <\property name="" value="">
,用於給簡單型別的屬性賦值。
需要在屬性上使用註解@Value,該註解的 value 屬性用於指定要注入的值。使用該註解完成屬性注入時,類中無需 setter。當然,若屬性有 setter,則也可將其加到 setter 上。
使用例項:
- 在屬性定義的上面使用,無需 setter ,推薦使用
@Componnet("student")
public class Student{
// @Value(value = "張san"),value屬性可不寫
@Value("張san")
private String name;
@Value("29")
private int age;
}
- 在 setter 上使用
@Componnet("student")
public class Student{
private String name;
private int age;
@Value("張三")
public void setName(String name) {
this.name = name;
}
@Value("29")
public void setAge(String age) {
this.age = age;
}
}
3、@Scope
功能同 <\bean> 的scop 屬性相同,在實體類上使用,用於設定 bean 的作用域。
- @Scope("singleton"):單例
- @Scope("prototype"):多例
4、@Atuowired(不推薦使用了)
功能與 <bean ... autowire="">
相同,用於為引用型別的屬性賦值。@Atuowired 預設使用的是 byType 自動從容器中裝配 Bean。
4.1、byType
byType 是 @Atuowired 的預設方式,直接在屬性上使用,類中無需 setter。若屬性有 setter,也可將其加到 setter 上。推薦直接在屬性上使用。
使用例項:
@Component("student")
public class Student {
@Value("16")
private int age;
@Autowired
private School school;
}
///////////////////////////////////////////////////////////////////////
@Component("school")
public class School {
@Value("3000")
private int area;
}
4.2、byName
需要再借助另一個註解 @Qualifier("容器中 bean 的 id"),才可以更改 @Atuowired 的自動裝配方式。
@Autowirted
@Qualifier(value="容器中bean的id")
使用例項:
@Component("student")
public class Student {
@Value("16")
private int age;
@Autowired
@Qualifier("stuSchool")
private School school;
}
///////////////////////////////////////////////////////////////////////
@Component("stuSchool")
public class School {
@Value("3000")
private int area;
}
3.3、required
required 是 @Autowired 的一個屬性,預設值為 true。建議使用 true
- true 表示如果引用型別賦值失敗,程式報錯終止執行
- false 表示如果引用型別賦值失敗,程式正常執行,引用型別賦為 null、
@Component("student")
public class Student {
@Value("16")
private int age;
@Autowired(required=true)
private School school;
}
4、@Resource
@Resource 是 JDK 的註解,Spring 提供了對它的支援。
同 @Atuowired 一樣,@Resource 也是既可以 byType,也可以 byName,預設是 byName。
@Resource 可用在屬性上,也可以用在 setter 上,推薦直接用在屬性上。
4.1、byType
@Resource 註解若不帶任何引數, 採用預設 byName 的方式注入,若 byName 失敗,則轉而使用 byType。
使用例項:
@Component("student")
public class Student {
@Value("16")
private int age;
@Resource
private School school;
}
///////////////////////////////////////////////////////////////////////
@Component("stuSchool")
public class School {
@Value("3000")
private int area;
}
4.2、byName
@Resource 註解指定其 name 屬性的值,則 name 的值即為按照名稱進行匹配的 Bean 的 id。
@Component("student")
public class Student {
@Value("16")
private int age;
@Resource(name="stuSchool")
private School school;
}
///////////////////////////////////////////////////////////////////////
@Component("stuSchool")
public class School {
@Value("3000")
private int area;
}
5、註解與XML對比
註解的優點:
- 方便
- 直觀
- 高效(程式碼少,沒有配置檔案的書寫那麼複雜)、
註解的缺點:
- 以硬編碼的方式寫入到 Java 程式碼中,修改是需要重新編譯程式碼的
XML 方式優點是:
- 配置和程式碼是分離的
- 在 xml 中做修改,無需編譯程式碼,只需重啟伺服器即可將新的配置載入
缺點:
- 編寫麻煩,效率低,大型專案過於複雜
最佳實踐:註解為主,配置檔案為輔