参考文章
https://www.cnblogs.com/leeSmall/p/10023593.html
spring IOC容器
bean定义
bean工厂通过bean定义来创建bean实例;
然后通过beanName获取到bean.
通过将bean定义注册到bean定义注册类, bean工厂就可以根据beanName获取到bean定义了
bean工厂代码:
bean定义注册map
bean实例map
DI依赖注入:
- 构造参数依赖:
也是在bean定义中描述好依赖的bean, 这样bean工厂就能知道创建指定bean需要先准备好那些依赖。
如果是bean依赖对象就用beanReference类型的
创建bean实例, 构造方法参数包括Java类型, 如果是引用类型则用BeanReference封装起来,
bean定义中定义构造方法, 构造方法参数包括 bean所依赖的其他bean, 这样bean定义其实就是bean的化身, bean定义包含了创建bean的所有资源。对于bean工厂来说只需要操作bean定义, 就能获取到 被创建的bean的所有信息,
bean工厂依赖于bean定义, 而bean定义屏蔽掉了不同bean的差异。并且对成员变量和构造方法赋值
bean工厂通过bean的构造方法创建bean实例
在创建bean定义实例的时候,需要设置构造方法参数; 如果bean有多个构造方法或者默认的无参构造, 需要被自定注入的成员变量怎么设置呢?
//构造参数存放属性
private List<?> constructorArgumentValues; - 成员属性依赖
在bean定义中定义属性依赖
List<PropertyValue> getPropertyValues();
//把真正的值v设置到属性p里面 即属性p依赖的值v
p.set(instance, v);
注意:属性依赖是允许循环依赖的,因为是在实例创建好之后才设置属性依赖的值的!!!
所以定义一个bean需要注意:
针对同一个成员变量, 要么用构造参数实现di;并且只能写一个构造方法, 否则就没办法决定用哪个构造方法了。
要么用注解成员属性的的方式来实现di
这样写ioc容器没办法通过构造方法创建BComponent对象,因为a和b的初始值没办法给到.png
这样写ioc容器可以通过构造方法创建BComponent对象,因为可以通过创建AComponent对象bean,然后从容器中取出来注入到构造方法的参数- 构造参数依赖(通过构造参数实现di):.png
成员属性依赖 (通过注解实现di).png