作者: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" 即可

完整代码

Github

参考资料

小马哥讲Spring核心编程思想

Spring中的依赖查找和依赖注入的更多相关文章

  1. 轻松了解Spring中的控制反转和依赖注入(二)

    紧接上一篇文章<轻松了解Spring中的控制反转和依赖注入>讲解了SpringIOC和DI的基本概念,这篇文章我们模拟一下SpringIOC的工作机制,使我们更加深刻的理解其中的工作. 类 ...

  2. Spring中的控制反转和依赖注入

    Spring中的控制反转和依赖注入 原文链接:https://www.cnblogs.com/xxzhuang/p/5948902.html 我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达 ...

  3. 轻松了解Spring中的控制反转和依赖注入(一)

    我们回顾一下计算机的发展史,从最初第一台计算机的占地面积达170平方米,重达30吨,到现如今的个人笔记本,事物更加轻量功能却更加丰富,这是事物发展过程中的一个趋势,在技术领域中同样也是如此,企业级Ja ...

  4. 1.spring.net Look-up Method 查找方法的注入(方法是抽象的需要spring.net注入)

    .为什么需要查找方法的注入 当Object依赖另一个生命周期不同的Object,尤其是当singleton依赖一个non-singleton时,常会遇到不少问题,Lookup Method Injec ...

  5. Spring中为什么不建议使用字段注入

    在使用Idea中通过注解注入字段时是否遇见过这样一个提示: Field injection is not recommended(不推荐使用字段注入) 一. 什么是字段注入,Spring中依赖注入的方 ...

  6. 由一个RABBITMQ监听器死循环引出的SPRING中BEAN和MAPPER接口的注入问题

    1 @Slf4j 2 @RestController 3 @Component 4 public class VouchersReceiverController implements Message ...

  7. Spring中依赖注入的四种方式

    在Spring容器中为一个bean配置依赖注入有三种方式: · 使用属性的setter方法注入  这是最常用的方式: · 使用构造器注入: · 使用Filed注入(用于注解方式). 使用属性的sett ...

  8. Spring是什么+控制反转和依赖注入

    Spring是一个开源框架,是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架. 原因: (1)通过控制反转(IOC)达到松耦合,IOC也就是把控制权交出去,在使用中直接得到对象 (2)提 ...

  9. 【Spring】IoC容器 - 依赖查找

    前言 上一篇文章已经学习了[IoC的主要实现策略]有2种: 1.依赖查找 2.依赖注入 这里稍加详细的介绍一下依赖查找 1.依赖查找的方式 依赖查找的方式可以以多种维度来划分: 1.按名称/类型/注解 ...

随机推荐

  1. Codeforces Round #656 (Div. 3) C. Make It Good

    题目链接:https://codeforces.com/contest/1385/problem/C 题意 去除一个数组的最短前缀使得余下的数组每次从首或尾部取元素可以排为非减序. 题解一 当两个大数 ...

  2. WIN7使用msg命令发送消息心得

    昨天搞了一下午+一晚上,终于捣鼓出了一些奇奇怪怪的操作,成功发送了消息. 应实验要求,博主有幸在家里搞到了两台win7,其他的系统是不是这么操作就不太清楚了. 一开始实验指导书上是用net send发 ...

  3. CodeForces 893C (并查集板子题)

    刷题刷到自闭,写个博客放松一下 题意:n个人,m对朋友,每寻找一个人传播消息需要花费相应的价钱,朋友之间传播消息不需要花钱,问最小的花费 把是朋友的归到一起,求朋友中花钱最少的,将所有最少的加起来. ...

  4. URAL - 1029 dp

    题意: n层楼,每层楼有m个房间.找出一个路径从第一层到达第M层,使得路径上的所有数的和是所有可达路径中最小的,每次上到下一层以后就不能再上去,依次输出路径上的各点在所在层的列数. 题解: 参考链接: ...

  5. EFCore学习记录--数据访问技术人门2

    1 code fist 1.创建实体类: 2.创建DbContext类: mysql连接字符串是:Server=127.0.0.1;Port=3306;Database=BlogDb; User=ro ...

  6. 【非原创】codeforces 1070C Cloud Computing 【线段树&树状数组】

    题目:戳这里 学习博客:戳这里 题意:有很多个活动,每个活动有持续天数,每个活动会在每天提供C个CPU每个CPU价格为P,问需要工作N天,每天需要K个CPU的最少花费. 解题思路:遍历每一天,维护当前 ...

  7. codeforces 1010 C. Border【exgcd】

    题目链接:戳这里 学习博客:戳这里 题意:给n种数,n种数取任意个任意组合相加为sum,求sum%k有哪些值. 解题思路: 由exgcd可知(具体用到的是贝祖定理),ax + by = c,满足gcd ...

  8. Java之先行发生原则与volatile关键字详解

    volatile关键字可以说是Java虚拟机提供的最轻量级的同步机制,但是它并不容易完全被正确.完整地理解,以至于许多程序员都习惯不去使用它,遇到需要处理多线程数据竞争问题的时候一律使用synchro ...

  9. spring-cloud-netflix-hystrix-dashboard

    Hystrix-dashboard是一款针对Hystrix进行实时监控的工具,通过Hystrix Dashboard我们可以在直观地看到各Hystrix Command的请求响应时间, 请求成功率等数 ...

  10. LWIP再探----内存堆管理

    LWIP的内存管理主要三种:内存池Pool,内存堆,和C库方式.三种方式中C库因为是直接从系统堆中分配内存空间且易产生碎片因此,基本不会使用,其他两种是LWIP默认全部采用的方式,也是综合效率和空间的 ...