Spring-ioc底层源码初步理解和解析
IOC是什么
IoC成为依赖注入(DI),是一个对象定义依赖关系的过程,对象只通过构造函数参数,工厂方法的参数或对象实例构造或工厂方法返回在对象实例上设置的属性来定义它们所使用的其他对象,然后容器在创建bean时注入这些依赖项,这个过程本质是bean本身的逆过程,因此称为控制反转(IoC)
bean是怎么注册到IoC容器
AliasRegistry
别名注册器 bean的name作为key ,
extend BeanDefinitionRegistry
BeanDefinitionRegistry
bean定义注册器 ConcurrentHashMap
bean的id作为key 注册到容器中
BeanDefinition
bean定义 承载bean属性(scope init-method)
BeanFactory
bean工厂 BeanDefinition交给工厂 BeanDefinitionRegistry
getBean(name) 找到BeanDefinition创建实例
简单IoC底层bean生产过程
DefaultListableBeanFactory registry = new DefaultListableBeanFactory();
BeanDefinition definition = new RootBeanDefinition(ServiceImpl.class);
registry.registerBeanDefinition("Service", definition);
System.out.println(registry.getBeanDefinition("Service"));
System.out.println(registry.getBean("Service"));
AutowireMode的构造模式
方法
BeanDefinition.setAutowireMode(num)
不传入构造方法时,用无参构造为优先选择
num=1
构造时,用构造器的方法名字为优先选择
num=2
构造时,用构造器传入的参数为优先选择
num=3
构造时,用构造器传入的参数数量多为优先选择(贪婪构造模式)
IoC启动时候的构造流程
- 容器启动的时候,什么时候注册业务bean
xml配置文件配置的bean
在创建beanFactory的过程中注入容器
注解方式的bean,在随后调用invokeBeanFactoryPostProcessors(引用BeanFactory后置方法)中注册bean
-
是否创建bean
容器启动时,会创建non-lazy-init的bean(第一次只创建非懒加载的bean) -
创建bean的流程
AbstractBeanFactory --> doGetBean #bean工厂 创建 bean
#创建前从singletonObjects(缓存) 中获取单例,如果缓存中没有,对单例是不是正在创建进行判断(如果正在创建, – > 放入earlysingletonObject)(解决相互调用的循环依赖问题),最后创建新的bean。 创建后,将newSingleton置为true,然后通过addSingleton,用singletonObject.put放入单例对向池。
DefaultsingletonBeanRegistry – > getsingleton
#第二次调用后置处理器,创建bean实例,并加入包装类BeanWrapper中返回
AbstractAutowireCapableBeanFactory – > creatBeanInstance
反射原理,动态创建对象。
(通过 beanFactory,
setter方法
无参构造器) – > 对Autowire的构造器进行判断,1 2 3模式。
#初始化bean 调用init方法
AbstractAutowireCapableBeanFactory --> initializeBean
tis: 由此见,可以通过实现InitializingBean接口,来完成自定义初始化方法。
#beanFactory和Factorybean的逻辑
最终bean 通过AbstractBeanFactory – > getObjectForBeanInstance 返回
(不是FactoryBean直接返回普通的bean对象)
!(beanInstance instanceof FactoryBean)
||
BeanFactoryUtils.insFactoryDereference(name) -->
name传入进行判断,
name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)
"BeanFactory.FACTORY_BEAN_PREFIX == ‘&’’
含义:name前面加个‘&’,返回beanFactory对象。