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





