Spring中的依賴查詢和依賴注入
阿新 • • 發佈:2021-03-01
作者:[Grey](https://www.cnblogs.com/greyzeng/)
原文地址:
[語雀](https://www.yuque.com/greyzeng/mnc4mc/oshvxb)
[部落格園](https://www.cnblogs.com/greyzeng/p/14459565.html)
## 依賴查詢
Spring IoC 依賴查詢分為以下幾種方式
- 根據 Bean 名稱查詢
- 實時查詢
- 延遲查詢
- 根據 Bean 型別查詢
- 單個 Bean 物件
- 集合 Bean 物件
- 根據 Bean 名稱 + 型別查詢
- 根據 Java 註解查詢
- 單個 Bean 物件
- 集合 Bean 物件
以下示例基於spring-framework 5.2.13.RELEASE 版本, 通過Maven管理專案
### 根據Bean名稱實時查詢
pom.xml 檔案引入如下依賴
```xml
org.springframework
spring-context
```
定義一個User作為Domain
```java
public class User {
private Long id;
private String name;
// set / get / toString方法略
}
```
在resources目錄下建立META—INF目錄,同時新建一個dependency-lookup.xml檔案
```xml
```
在xml檔案中配置如下內容
```xml
```
新建測試類
```java
package org.snippets.spring.ioc.overview.dependency.lookup;
/**
* 通過名稱查詢
*/
public class DependencyLookup {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-lookup.xml");
lookupRealtime(beanFactory);
}
// 實時查詢(按Bean名稱)
private static void lookupRealtime(BeanFactory beanFactory) {
User user = (User) beanFactory.getBean("user");
System.out.println(user);
}
}
```
輸出結果
```
User{id=1, name='張三'}
```
### 根據Bean名稱延遲查詢
在上例中的xml檔案中配置
```xml
```
新建測試類
```java
public class DependencyLookup {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-lookup.xml");
lookupLazy(beanFactory);
}
// 延遲查詢(按Bean名稱)
private static void lookupLazy(BeanFactory beanFactory) {
ObjectFactory objectFactory = (ObjectFactory) beanFactory.getBean("objectFactory");
User user = objectFactory.getObject();
System.out.println(user);
}
}
```
執行結果
```
User{id=1, name='張三'}
```
### 根據Bean型別查詢單個物件
```java
private static void lookupByTypeSingle(BeanFactory beanFactory){
User user=beanFactory.getBean(User.class);
System.out.println(user);
}
```
### 根據Bean型別查詢集合物件
```java
private static void lookupByTypeCollection(BeanFactory beanFactory){
if(beanFactory instanceof ListableBeanFactory){
ListableBeanFactory beanFactory1=(ListableBeanFactory)beanFactory;
Map users=beanFactory1.getBeansOfType(User.class);
System.out.println(users);
}
}
```
### 根據Java註解來查詢多個物件
首先我們定義一個註解@Super
```java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Super { }
```
然後我們定義一個User的子類SuperUser,並標註@Super註解
```java
@Super
public class SuperUser extends User {
private String address;
// set / get / toString方法忽略
}
```
我們在xml中做如下配置
```xml
```
如果通過User.class型別來找Bean,可能會找到SuperUser和User兩個,但是加了Primary="true"這個配置,則只會找superUser這個Bean
接下來就是通過註解來找到Bean的程式碼
```java
private static void lookupByAnnotations(BeanFactory beanFactory) {
if (beanFactory instanceof ListableBeanFactory) {
ListableBeanFactory beanFactory1 = (ListableBeanFactory) beanFactory;
Map users = (Map) beanFactory1.getBeansWithAnnotation(Super.class);
System.out.println(users);
}
}
```
列印結果:
```
{superUser=SuperUser{address='廣州'} User{id=1, name='張三'}}
```
## 依賴注入
Spring IoC 依賴注入分為以下幾種方式
- 根據 Bean 名稱注入
- 根據 Bean 型別注入
- 單個 Bean 物件
- 集合 Bean 物件
- 注入容器內建 Bean 物件
- 注入非 Bean 物件
- 注入型別
- 實時注入
- 延遲注入
增加UserRepository
```java
public class UserRepository {
private Collection users; // 自定義Bean
private BeanFactory beanFactory; // 內建非 Bean(依賴)
private ObjectFactory objectFactory;
// 省略 set/get/toString方法
}
```
首先我們新建一個配置檔案dependency-injection.xml
引入上一例中的dependency-lookup.xml,並增加一個Bean的配置, 並且配置手動注入這個Bean中屬性資訊
```xml
```
測試
```java
public class DependencyInjection {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-injection.xml");
UserRepository userRepository = beanFactory.getBean("userRepository", UserRepository.class);
System.out.println(userRepository.getUsers());
}
}
```
可以打印出注入的user資訊
也可以實現自動注入,我們以按型別自動注入為例,修改xml配置
```xml
```
增加autowire="byType" 即可
## 完整程式碼
[Github](https://github.com/GreyZeng/thinking-in-spring/java-beans-demo)
## 參考資料
[小馬哥講Spring核心程式設計思想](https://time.geekbang.org/course/intro/10