03 Spring IoC 依赖来源

本文探讨Spring框架中IoC容器的依赖注入原理,详细分析依赖来源包括自定义Bean、容器内建Bean及内建依赖的区别。通过实例演示如何注入自定义Bean与内建依赖。

(1)Spring IoC 依赖来源:

  • 自定义的Bean,通常是业务Bean,例如UserRepository对象,可以通过getBean获取
  • 容器内建的Bean对象,不是我们自己业务方或者自己的应用来构建的,而是Spring 容器内部建立的,例如Environment、BeanDefinitions 和 Singleton Objects。可以通过getBean获取
  • 容器内建的依赖容器内非Bean,例如 BeanFactory,无法通过getBean获取。是通过AutowireCapableBeanFactory中的resolveDependency方法来注册

说明:

依赖不仅仅来源于我们自定义时的Bean,也可能是内建的一个Bean对象,还有可能是容器内建的所谓的依赖(非Spring的Bean)

总体上说,依赖可以大体上分为两类:

  • 一个是普通的Bean
  • 非Bean

(2)什么是内建的Bean对象

例如 Environment对象,它是外部化配置和profile的一个综合体,可通过getBean的方法去查找。

并没有在我们的配置文件中去定义,是内部容器默认初始化了一些Bean.

package org.binsoft.thinking.in.spring.ioc.overview.dependency.injection;

import org.binsoft.thinking.in.spring.ioc.overview.annotation.Super;
import org.binsoft.thinking.in.spring.ioc.overview.domain.User;
import org.binsoft.thinking.in.spring.ioc.overview.repository.UserRepository;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.env.Environment;

import java.util.Map;

/**
 * 依赖注入示例
 *
 * @author binsoft
 * @version 1.0
 * @date 2021/1/1 11:53
 */
public class DependencyInjectionDemo {
    public static void main(String[] args) {
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-injection-context.xml");

        //(1)自定义的Bean
        UserRepository userRepository = beanFactory.getBean("userRepository", UserRepository.class);
        System.out.println(userRepository.getUsers());


        //(2)依赖注入(内建的依赖)
        System.out.println(userRepository.getBeanFactory());// 说明不是Bean对象,而是一个内建的依赖
        System.out.println(userRepository.getBeanFactory() == beanFactory); // false

        //(3)容器内建Bean,不是我们自己业务方或者自己的应用来构建的,而是Spring 容器内部建立的,由容器默认初始化了一些Bean
        Environment environment = beanFactory.getBean(Environment.class);
        System.out.println("获取 Environment 类型的 Bean: " + environment);
        //获取 Environment 类型的 Bean: StandardEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[PropertiesPropertySource {name='systemProperties'}, SystemEnvironmentPropertySource {name='systemEnvironment'}]}


    }

}

总结:依赖的来源,并不是仅狭隘于我们自定义的Bean,也可能来自于容器的Bean对象以及内建的依赖。

 

(3)Spring容器内建Bean和内建依赖的区别

内建的依赖也是依赖某个Bean,既然这个依赖的Bean不是自定的Bean,它必然是容器内建的Bean,那么容器内建的依赖和内建Bean的区别主要在于:

内建的Bean是普通的Spring Bean ,包括BeanDefinitions和Singleton Objects

内建依赖则是通过AutowireCapableBeanFactory中的resolveDependency方法来注册,这并非是一个Spring Bean, 无法通过依赖getBean查找获取。

进一步说:

内建依赖指的是DefaultListableBeanFactory属性resolvableDependencies这个map里面保存的bean,

内建bean指的是通过DefaultSingletonBeanRegistry#registerSingleton手动注册的bean,

区别是依赖注入的时候比如@AutoWired(AutowiredAnnotationBeanPostProcessor处理)会调用DefaultListableBeanFactory#resolveDependency方法去resolvableDependencies里面找,然后注入内建依赖等,

而依赖查找getBean是不会去找的。

实际上,Spring IoC 底层容器就是指的 BeanFactory 的实现类,大多数情况是 DefaultListableBeanFactory 这个类,它来管理 Spring Beans,

而 ApplicationContext 通常为开发人员接触到的 IoC 容器,它是一个 Facade,Wrap 了 BeanFactory 的实现。通常情况下,内建的依赖指的是这个BeanFactory ,如下图

 

从图中可以看出,依赖注入的两个内建的依赖都是DefaultListableBeanFactory@25d250c6

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DreamCatcher

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值