1. 程式人生 > >Spring中的依賴查詢和依賴注入

Spring中的依賴查詢和依賴注入

作者:[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