Spring(05)IoC 依赖查找

目录

  • Spring(05)IoC 依赖查找

    • 1. 依赖查找的今世前生
    • 2. 单一类型依赖查找
    • 3. 集合类型依赖查找
    • 4. 层次性依赖查找
    • 5. 延迟依赖查找
    • 6. 安全依赖查找
    • 7. 内建可查找的依赖
    • 8. 依赖查找中的经典异常
    • 9. 面试题精选

Spring(05)IoC 依赖查找

Spring 核心编程思想目录:https://www.cnblogs.com/binarylei/p/12290153.html

1. 依赖查找的今世前生

  • 单一类型依赖查找

    • JNDI:javax.naming.Context
    • JavaBeans :java.beans.beancontext.BeanContext
  • 集合类型依赖查找
    • java.beans.beancontext.BeanContext
  • 层次性依赖查找
    • java.beans.beancontext.BeanContextServices

tomcat架构分析 (JNDI配置)

tomcat架构分析 (JNDI体系绑定)

2. 单一类型依赖查找

单一类型依赖查找接口 - BeanFactory

  • 根据 Bean 名称查找

    • getBean(String)
    • Spring 2.5 覆盖默认参数:getBean(String, Object...)
  • 根据Bean 类型查找
    • Bean 实时查找

      • Spring 3.0 getBean(Class)
      • Spring 4.1 覆盖默认参数:getBean(Class, Object...)
    • Spring 5.1 Bean 延迟查找
      • getBeanProvider(Class)
      • getBeanProvider(ResolvableType)
  • 根据 Bean 名称 + 类型查找:getBean(String, Class)

3. 集合类型依赖查找

集合类型依赖查找接口 - ListableBeanFactory

  • 根据 Bean 类型查找

    • 获取同类型 Bean 名称列表

      • getBeanNamesForType(Class)
      • Spring 4.2 getBeanNamesForType(ResolvableType)
    • 获取同类型 Bean 实例列表
      • getBeansOfType(Class) 以及重载方法
  • 通过注解类型查找
    • Spring 3.0 获取标注类型Bean 名称列表

      • getBeanNamesForAnnotation(Class<? extends Annotation>)
    • Spring 3.0 获取标注类型Bean 实例列表
      • getBeansWithAnnotation(Class<? extends Annotation>)
    • Spring 3.0 获取指定名称+ 标注类型Bean 实例
      • findAnnotationOnBean(String, Class<? extends Annotation>)

思考: getBeanNamesForType 和 getBeansOfType 区别?

getBeanNamesForType 是根据 BeanDefinition 或 FactoryBean#getObjectType 判断对象类型,不会进行对象的初始化。而 getBeansOfType 可能将 bean 提前初始化,导致 bean 初始化不完全。

@Override
public String[] getBeanNamesForType(@Nullable Class<?> type) {
    return getBeanNamesForType(type, true, true);
}

@Override
public <T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException {
    return getBeansOfType(type, true, true);
}
@Override
public <T> Map<String, T> getBeansOfType(@Nullable Class<T> type,
        boolean includeNonSingletons, boolean allowEagerInit) throws BeansException {
    String[] beanNames = getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
    Map<String, T> result = new LinkedHashMap<>(beanNames.length);
    for (String beanName : beanNames) {
        // 最大的不同在这里:getBean(beanName) 实例化对象
        Object beanInstance = getBean(beanName);
        if (!(beanInstance instanceof NullBean)) {
            result.put(beanName, (T) beanInstance);
        }
    }
    return result;
}

说明: 无论是 getBeanNamesForType 还是 getBeansOfType 都会通过调用 getBeansOfType(type, true, true) 方法,根据类型查找 bean。不同的是 getBeansOfType 在查找到对应的 beanNames 后会调用 getBean(beanName) 实例化对象。

4. 层次性依赖查找

层次性依赖查找接口 - HierarchicalBeanFactory

  • 双亲 BeanFactory:getParentBeanFactory()
  • 层次性查找
    • 根据 Bean 名称查找

      • 基于 containsLocalBean 方法实现
    • 根据 Bean 类型查找实例列表
      • 单一类型:BeanFactoryUtils#beanOfType
      • 集合类型:BeanFactoryUtils#beansOfTypeIncludingAncestors
    • 根据 Java 注解查找名称列表
      • BeanFactoryUtils#beanNamesForTypeIncludingAncestors

5. 延迟依赖查找

Bean 延迟依赖查找接口

  • org.springframework.beans.factory.ObjectFactory
  • org.springframework.beans.factory.ObjectProvider
    • Spring 5 对 Java 8 特性扩展
    • 函数式接口
      • getIfAvailable(Supplier)
      • ifAvailable(Consumer)
    • Stream 扩展- stream()

6. 安全依赖查找

依赖查找类型 代表实现 是否安全
单一类型查找 BeanFactory#getBean
ObjectFactory#getObject
ObjectProvider#getIfAvailable
集合类型查找 ListableBeanFactory#getBeansOfType
ObjectProvider#stream

注意:层次性依赖查找的安全性取决于其扩展的单一或集合类型的 BeanFactory 接口。

7. 内建可查找的依赖

AbstractApplicationContext 内建可查找的依赖

Bean 名称 Bean 实例 使用场景
environment Environment 对象外部化配置以及Profiles
systemProperties java.util.Properties 对象Java 系统属性
systemEnvironment java.util.Map 对象操作系统环境变量
messageSource MessageSource 对象国际化文案
lifecycleProcessor LifecycleProcessor 对象Lifecycle Bean 处理器
applicationEventMulticaster ApplicationEventMulticaster 对象Spring 事件广播器

注解驱动Spring 应用上下文内建可查找的依赖(部分)

Bean 名称 Bean 实例 使用场景
org.springframework.context.annotation
.internalConfigurationAnnotationProcessor
ConfigurationClassPostProcessor 处理Spring 配置类
org.springframework.context.annotation
.internalAutowiredAnnotationProcessor
AutowiredAnnotationBeanPostProcessor 处理@Autowired 以及@Value注解
org.springframework.context.annotation
.internalCommonAnnotationProcessor
CommonAnnotationBeanPostProcessor (条件激活)处理JSR-250 注解,如@PostConstruct 等
org.springframework.context.event
.internalEventListenerProcessor
EventListenerMethodProcessor 处理标注@EventListener 的Spring 事件监听方法
org.springframework.context.event
.internalEventListenerFactory
DefaultEventListenerFactory @EventListener 事件监听方法适配为ApplicationListener
org.springframework.context.annotation
.internalPersistenceAnnotationProcessor
PersistenceAnnotationBeanPostProcessor (条件激活)处理JPA 注解场景

8. 依赖查找中的经典异常

异常类型 触发条件(举例) 场景举例
NoSuchBeanDefinitionException 当查找Bean 不存在于IoC 容器时 BeanFactory#getBean
ObjectFactory#getObject
NoUniqueBeanDefinitionException 类型依赖查找时,IoC 容器存在多个Bean 实例 BeanFactory#getBean(Class)
BeanInstantiationException 当Bean 所对应的类型非具体类时 BeanFactory#getBean
BeanCreationException 当Bean 初始化过程中 Bean 初始化方法执行异常时
BeanDefinitionStoreException 当BeanDefinition 配置元信息非法时 XML 配置资源无法打开时

9. 面试题精选

ObjectFactory 与 BeanFactory 的区别?

答:ObjectFactory 与 BeanFactory 均提供依赖查找的能力。

不过 ObjectFactory 仅关注一个或一种类型的 Bean 依赖查找,并且自身不具备依赖查找的能力,能力则由 BeanFactory 输出。BeanFactory 则提供了单一类型、集合类型以及层次性等多种依赖查找方式。

BeanFactory.getBean 操作是否线程安全?

答:BeanFactory.getBean 方法的执行是线程安全的,实现过程中会增加互斥锁。

Spring 依赖查找与注入在来源上的区别?

答:答案将《Spring IoC依赖注入》以及《Spring IoC依赖来源》章节中继续讨论。

原文地址:https://www.cnblogs.com/binarylei/p/12297797.html

时间: 2024-09-30 11:14:07

Spring(05)IoC 依赖查找的相关文章

Spring.net Ioc 依赖注入

控制反转 (Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心. 控制反转一般分为两种类型,依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup). Spring.NET 为建立企业级应用提供了一套轻量级的解决方案.通过Spring.NET,我们可以用统一且透明的方式来配置应用程序.Spring.NET的重点是为中间层提供声明式事务管理,以

浅析Spring IOC、依赖注入(DI)和依赖查找(DL)

为什么要用IOC? 第一:对象的实例化不是一件简单的事情,比如对象的关系比较复杂,依赖关系往往需要程序员去维护,这是一件非常头疼的事. 第二:解耦,由容器去维护具体的对象 第三:托管了类的产生过程,比如我们需要在类的产生过程中做一些处理,最直接的例子就是代理,如果有容器程序可以把这部分过程交给容器,应用程序则无需去关心类是如何完成代理的 控制反转(Inverse of Control) 控制反转即IoC(Incersion of Control),从字面上理解就是控制反转,将对在自身对象中的一个

关于Spring IOC (依赖注入)你需要知道的一切

[版权申明]未经博主同意,不允许转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/54561302 出自[zejian的博客] <Spring入门经典>这本书无论对于初学者或者有经验的工程师还是很值一看的,最近花了点时间回顾了Spring的内容,在此顺带记录一下,本篇主要与spring IOC相关 ,这篇博文适合初学者也适合spring有过开发经验的工程师,前者可用于全面了解Spring IOC的知识点,后者且

spring(3)------控制反转(IOC)/依赖注入(DI)

一,spring核心概念理解 控制反转: 控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理. 所谓的"控制反转"概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器. 没有控制反转这种模式前,你创建一个对象,在什么地方用,你得单独通过关键字new出来用, 但现在可以不用这样,你把new对象的权利交给spring配置文件,通过配置文件来'new', 就是权利的反转,你以前干的事

Spring(06)IOC 依赖注

目录 Spring(06)IOC 依赖注 1. 依赖注入的模式和类型 1.1 依赖注入模式 1.2 依赖注入类型 2. 自动绑定(Autowiring) 3. 自动绑定(Autowiring)模式 4. 自动绑定(Autowiring)限制和不足 5. Setter 方法依赖注入 6. 构造器依赖注入 7. 字段注入 8. 方法注入 9. 回调注入 10. 依赖注入类型选择 11. 基础类型注入 12. 集合类型注入 13. 限定注入 14. 延迟依赖注入 15. 依赖处理过程 16. @Aut

Spring IoC 依赖注入(二)源码分析

目录 Spring IoC 依赖注入(二)源码分析 1. 依赖注入口 - populateBean 1.1 doCreateBean 1.2 populateBean 2. 手动注入 2.1 相关的类说明 2.2 applyPropertyValues 2.3 BeanDefinitionValueResolver 2.4 依赖检查 2. 自动注入 2.1 那些字段会自动注入 2.2 名称注入 2.3 类型注入 Spring IoC 依赖注入(二)源码分析 本章主要分析 Spring IoC 依

spring学习——Ioc基础四(Di之循环依赖)

一. 什么是循环依赖 循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比如CircleA引用CircleB,CircleB引用CircleC,CircleC引用CircleA,则它们最终反映为一个环.此处不是循环调用,循环调用是方法之间的环调用.如图3-5所示: 图3-5 循环引用 循环调用是无法解决的,除非有终结条件,否则就是死循环,最终导致内存溢出错误. Spring容器循环依赖包括构造器循环依赖和setter循环依赖,那Spring容器如何解决循环依赖呢?首先让我们来定义循

Spring之ioc控制反转(依赖注入)

个人感觉依赖注入比控制反转更好理解,所以下面就只说依赖注入: spring的整体结构示意图: 一.spring 中的概念 beanFactory容器 1.容器是spring框架的核心,容器使用ioc依赖注入来管理所有组成应用系统的组件. 2.spring中的两种容器: beanFactory  这个容器提供了基础的依赖注入支持,而且是延迟加载的,而 applicationcontext是对beanFactory 这个容器的扩展, 3.beanFactory :beanFactory就是一个Bea

Spring的IOC容器—依赖注入

前面一篇博客大致讲了一下Spring的IOC容器的原理,IOC即控制反转主要是依靠依赖注入的方式来实现的.依赖注入是指所依赖的对象不是由自己new出来的,而是用别的方式像打针似的注入进来. 其实说白了不管是控制反转还是依赖注入都说明了Spring采用动态.灵活的方式来管理各种对象. Spring的依赖注入对调用者和被调用者几乎没有任何要求,完全支持对POJO之间依赖关系的管理.有以下几种注入方式: 1. Setter 注入 因为对于javaBean来说,我们可以通过setter和getter方法