做者: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" 便可