Spring中的依赖查找和依赖注入
作者:Grey
原文地址:
依赖查找
Spring IoC 依赖查找分为以下几种方式
根据 Bean 名称查找
- 实时查找
- 延迟查找
根据 Bean 类型查找
- 单个 Bean 对象
- 集合 Bean 对象
根据 Bean 名称 + 类型查找
根据 Java 注解查找
- 单个 Bean 对象
- 集合 Bean 对象
以下示例基于spring-framework 5.2.13.RELEASE 版本, 通过Maven管理项目
根据Bean名称实时查找
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='张三'}
根据Bean名称延迟查找
在上例中的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='张三'}
根据Bean类型查找单个对象
private static void lookupByTypeSingle(BeanFactory beanFactory){
User user=beanFactory.getBean(User.class);
System.out.println(user);
}
根据Bean类型查询集合对象
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);
}
}
根据Java注解来查询多个对象
首先我们定义一个注解@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 对象
注入容器內建 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" 即可
完整代码
参考资料
Spring中的依赖查找和依赖注入的更多相关文章
- 轻松了解Spring中的控制反转和依赖注入(二)
紧接上一篇文章<轻松了解Spring中的控制反转和依赖注入>讲解了SpringIOC和DI的基本概念,这篇文章我们模拟一下SpringIOC的工作机制,使我们更加深刻的理解其中的工作. 类 ...
- Spring中的控制反转和依赖注入
Spring中的控制反转和依赖注入 原文链接:https://www.cnblogs.com/xxzhuang/p/5948902.html 我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达 ...
- 轻松了解Spring中的控制反转和依赖注入(一)
我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达170平方米,重达30吨,到现如今的个人笔记本,事物更加轻量功能却更加丰富,这是事物发展过程中的一个趋势,在技术领域中同样也是如此,企业级Ja ...
- 1.spring.net Look-up Method 查找方法的注入(方法是抽象的需要spring.net注入)
.为什么需要查找方法的注入 当Object依赖另一个生命周期不同的Object,尤其是当singleton依赖一个non-singleton时,常会遇到不少问题,Lookup Method Injec ...
- Spring中为什么不建议使用字段注入
在使用Idea中通过注解注入字段时是否遇见过这样一个提示: Field injection is not recommended(不推荐使用字段注入) 一. 什么是字段注入,Spring中依赖注入的方 ...
- 由一个RABBITMQ监听器死循环引出的SPRING中BEAN和MAPPER接口的注入问题
1 @Slf4j 2 @RestController 3 @Component 4 public class VouchersReceiverController implements Message ...
- Spring中依赖注入的四种方式
在Spring容器中为一个bean配置依赖注入有三种方式: · 使用属性的setter方法注入 这是最常用的方式: · 使用构造器注入: · 使用Filed注入(用于注解方式). 使用属性的sett ...
- Spring是什么+控制反转和依赖注入
Spring是一个开源框架,是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架. 原因: (1)通过控制反转(IOC)达到松耦合,IOC也就是把控制权交出去,在使用中直接得到对象 (2)提 ...
- 【Spring】IoC容器 - 依赖查找
前言 上一篇文章已经学习了[IoC的主要实现策略]有2种: 1.依赖查找 2.依赖注入 这里稍加详细的介绍一下依赖查找 1.依赖查找的方式 依赖查找的方式可以以多种维度来划分: 1.按名称/类型/注解 ...
随机推荐
- 2019牛客暑期多校训练营(第二场)E.MAZE(线段树+dp)
题意:给你一个n*m的矩阵 你只能向左向右相下走 有两种操作 q次询问 一种是把一个单位翻转(即可走变为不可走 不可走变为可走) 另一种是询问从(1,x) 走到 (n,y)有多少种方案 思路:题目n为 ...
- 【bzoj 1202】[HNOI2005] 狡猾的商人(图论--带权并查集+前缀和)
题意:一个账本记录了N个月以来的收入情况,现在有一个侦探员不同时间偷看到M段时间内的总收入,问这个账本是否为假账. 解法:带权并查集+前缀和. 判断账本真假是通过之前可算到的答案与当前读入的值是否 ...
- hdu5360 Hiking
Problem Description There are n soda conveniently labeled by 1,2,-,n. beta, their best friends, want ...
- python爬虫下载小视频和小说(基础)
下载视频: 1 from bs4 import BeautifulSoup 2 import requests 3 import re 4 import urllib 5 6 7 def callba ...
- 国产网络测试仪MiniSMB - 如何3秒内创建出16,000条源/目标MAC地址号递增流
国产网络测试仪MiniSMB(www.minismb.com)是复刻smartbits的IP网络性能测试工具,是一款专门用于测试智能路由器,网络交换机的性能和稳定性的软硬件相结合的工具.可以通过此以太 ...
- 设置chromium的默认搜索引擎为Bing
设置 -> 搜索 -> 管理搜索引擎 第三项中添加: http://cn.bing.com/search?q=%s 即可.
- CURL (CommandLine Uniform Resource Locator) 简易教程!
1 http://curl.haxx.se/ http://curl.haxx.se/docs/httpscripting.html curl is an open source command li ...
- Sass && SCSS && Less
1 1 1 Sass && SCSS && Less 在线SCSS编辑工具: http://www.sassmeister.com/ Sass v3.4.21 1 tu ...
- 如何使用 js 实现一个 debounce 函数
如何使用 js 实现一个 debounce 函数 原理 防抖: 是指在指定的单位时间内,如果重复触发了相同的事件,则取消上一次的事件,重新开始计时! 实现方式 "use strict&quo ...
- frontends tools
frontends tools figma free online UI 可视化埋点 https://www.figma.com/files/recent cypress testing $ npm ...