做者:Greyhtml
原文地址:java
語雀git
博客園github
Spring IoC 依賴查找分爲如下幾種方式spring
根據 Bean 名稱查找編程
根據 Bean 類型查找dom
根據 Bean 名稱 + 類型查找測試
根據 Java 註解查找spa
如下示例基於spring-framework 5.2.13.RELEASE 版本, 經過Maven管理項目code
pom.xml 文件引入以下依賴
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency>
定義一個User做爲Domain
public class User { private Long id; private String name; // set / get / toString方法略 }
在resources目錄下創建META—INF目錄,同時新建一個dependency-lookup.xml文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> </beans>
在xml文件中配置以下內容
<?xml version="1.0"encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="user" class="org.snippets.spring.ioc.overview.dependency.domain.User"> <property name="id" value="1"/> <property name="name" value="張三"/> </bean> </beans>
新建測試類
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='張三'}
在上例中的xml文件中配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="user" class="org.snippets.spring.ioc.overview.dependency.domain.User"> <property name="id" value="1"/> <property name="name" value="張三"/> </bean> <bean id="objectFactory" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean"> <property name="targetBeanName" value="user"/> </bean> </beans>
新建測試類
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<User> objectFactory = (ObjectFactory<User>) beanFactory.getBean("objectFactory"); User user = objectFactory.getObject(); System.out.println(user); } }
運行結果
User{id=1, name='張三'}
private static void lookupByTypeSingle(BeanFactory beanFactory){ User user=beanFactory.getBean(User.class); System.out.println(user); }
private static void lookupByTypeCollection(BeanFactory beanFactory){ if(beanFactory instanceof ListableBeanFactory){ ListableBeanFactory beanFactory1=(ListableBeanFactory)beanFactory; Map<String, User> users=beanFactory1.getBeansOfType(User.class); System.out.println(users); } }
首先咱們定義一個註解@Super
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Super { }
而後咱們定義一個User的子類SuperUser,並標註@Super註解
@Super public class SuperUser extends User { private String address; // set / get / toString方法忽略 }
咱們在xml中作以下配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="user" class="org.snippets.spring.ioc.overview.dependency.domain.User"> <property name="id" value="1"/> <property name="name" value="張三"/> </bean> <bean id="superUser" class="org.snippets.spring.ioc.overview.dependency.domain.SuperUser" parent="user" primary="true"> <property name="address" value="廣州"/> </bean> <bean id="objectFactory" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean"> <property name="targetBeanName" value="user"/> </bean> </beans>
若是經過User.class類型來找Bean,可能會找到SuperUser和User兩個,可是加了Primary="true"這個配置,則只會找superUser這個Bean
接下來就是經過註解來找到Bean的代碼
private static void lookupByAnnotations(BeanFactory beanFactory) { if (beanFactory instanceof ListableBeanFactory) { ListableBeanFactory beanFactory1 = (ListableBeanFactory) beanFactory; Map<String, User> users = (Map) beanFactory1.getBeansWithAnnotation(Super.class); System.out.println(users); } }
打印結果:
{superUser=SuperUser{address='廣州'} User{id=1, name='張三'}}
Spring IoC 依賴注入分爲如下幾種方式
根據 Bean 名稱注入
根據 Bean 類型注入
注入容器內建 Bean 對象
注入非 Bean 對象
注入類型
增長UserRepository
public class UserRepository { private Collection<User> users; // 自定義Bean private BeanFactory beanFactory; // 內建非 Bean(依賴) private ObjectFactory<ApplicationContext> objectFactory; // 省略 set/get/toString方法 }
首先咱們新建一個配置文件dependency-injection.xml
引入上一例中的dependency-lookup.xml,並增長一個Bean的配置, 而且配置手動注入這個Bean中屬性信息
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd"> <import resource="dependency-lookup.xml"/> <bean id="userRepository" class="org.snippets.spring.ioc.overview.dependency.repo.UserRepository" > <!-- 手動注入 --> <property name="users"> <util:list> <ref bean="user"/> <ref bean="superUser"/> </util:list> </property> </bean> </beans>
測試
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 version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd"> <import resource="dependency-lookup.xml"/> <bean id="userRepository" class="org.snippets.spring.ioc.overview.dependency.repo.UserRepository" autowire="byType"> <!-- 自動注入--> </bean> </beans>
增長autowire="byType" 便可