Spring Bean
Ioc
ioc遵循了依赖导致原则,是一种思想,他将对象的创建由原本的开发者,通过依赖注入的方式,转移给了ioc容器.
组成
BeanFactory
基础的bean创建工厂,主要是提供了getbean(string name),通过名字获取对象.getType(string name)通过名字获取类型,isSingleton(string name)是否是单例等方法.
ApplicationContext
继承了BeanFactory,并提供了一些获取应用名的方法.属于高阶的IOC容器.
BeanDefinition
javabean对象在容器中的表现形式,包含了类的属性,行为,类型,依赖等功能.
实现过程
1.创建beanFactory,扫描resource包下面的xml文件或者@bean等spring容器注解标记的对象,生产一个beanName为元素的arrayList集合.2.实例化bean遍历beanName集合,查找到bean的依赖关系,以递归的方式,一层一层的去使用beanUtil.instance方法初始化bean.3.根据bean的依赖关系,用递归的方式一步步完成bean的依赖注入.
Bean的生命周期
核心步骤图解

1.AbstractBeanFactory.doGetBean方法
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 1.根据 beanName 尝试从缓存中获取 Bean,如果缓存中有,则直接return,如果缓存中没有,且Bean不在创建中则返回null
Object beanInstance = getSingleton(beanName);
...
if (!typeCheckOnly) {
//标记名称为 {beanName} 的 Bean 正在创建中
markBeanAsCreated(beanName);
}
// 2.创建 Bean。 虽然方法名称也叫 getSingleton ,但是它传入了一个可以创建 Bean 的匿名函数,它会在内部调用该匿名函数,进行 Bean 的“创建”
sharedInstance = getSingleton(beanName, () -> { return createBean(beanName, mbd, args); });
}
}
2.getSingleton(beanName)
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 从第一级缓存 singletonObjects 中取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 没取到,从第二级缓存 earlySingletonObjects 中取
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 还没取到,从第三级缓存 singletonFactories 中取出该 bean 的工厂对象
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 通过工厂对象生产该 bean 的实例,注意这里拿到的可能是一个 bean 的代理对象
singletonObject = singletonFactory.getObject();
// 然后添加到第二级缓存 earlySingletonObjects 中
this.earlySingletonObjects.put(beanName, singletonObject);
// 最后删除掉第三级缓存 singletonFactories 中该 bean 的工厂
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
}3.getSingleton(beanName, ObjectFactory<?>)
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
// 创建前的处理
beforeSingletonCreation(beanName);
//1.创建 bean。singletonFactory 对象,就是上面那段的匿名函数,getObject()方法对应的就是匿名函数的具体实现
singletonObject = singletonFactory.getObject();
// 创建后的处理
afterSingletonCreation(beanName);
// 2.将 bean 添加到缓存中
addSingleton(beanName, singletonObject);
return singletonObject;
}4.addSingleton()
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 将 Bean 添加到第一级缓存中
this.singletonObjects.put(beanName, singletonObject);
// 将 Bean 从第三级缓存中删除
this.singletonFactories.remove(beanName);
// 将 Bean 从第二级缓存中删除
this.earlySingletonObjects.remove(beanName);
// 标记 {beanName} 对应的 Bean 已创建
this.registeredSingletons.add(beanName);
}
}5.createBean(beanName, mbd, args)
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {
// 拿到 Bean 的 Definition 对象
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//如果是aop,则返回代理的对象
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// 调用 doCreateBean() 方法
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
}
}6.doCreateBean() 方法
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException {
// 1.实例化 Bean,并从返回的 BeanWrapper 包装类中取出 bean 对象。注意此时 bean 还是原始对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
final Object bean = instanceWrapper.getWrappedInstance();
// 是否”提前暴露“原始对象的引用,用于解决循环依赖。对于单例Bean,该变量一般为 true
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
//2.往第三级缓存中添加一个 ObjectFactory 接口的实现类,就是下面这个匿名函数,调用该匿名函数可以获得一个 bean 对象或者 bean 的代理对象,实现 AOP
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 3.填充属性(依赖注入)
populateBean(beanName, mbd, instanceWrapper);
// 4. Bean初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
7.addSingletonFactory()
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
// 如果 bean 不在第一级缓存中
if (!this.singletonObjects.containsKey(beanName)) {
// 将 ObjectFactory 接口的实现类,就是上一节中的匿名函数添加到第三级缓存中
this.singletonFactories.put(beanName, singletonFactory);
// 将 bean 从删除第二级缓存中删除
this.earlySingletonObjects.remove(beanName);
// 将该 bean 标记为已注册
this.registeredSingletons.add(beanName);
}
}
}8.populateBean()
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 1.基于 byName 的自动装配
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 2.基于 byType 的自动装配
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
//默认是AUTOWIRE_NO
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 3.填充属性
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
总结
实例化,为Bean分配内存空间。
属性赋值,填充属性和依赖注入。
初始化:
针对实现了Aware接口的bean,执行各种通知。
执行前置方法。
执行初始化方法。(@PostConstruct)
执行后置方法。
使用Bean,在程序中使用Bean。
销毁Bean,执行Bean的销毁方法。(@PreDestroy)
Bean的循环依赖
出现场景
1.构造方法里面.2.成员变量里面.
出现类型
1.单例2.原型
解决思路
spring对单例的成员变量的循环依赖进行了解决.主要思想是使用三级缓存,提前获取到实例对象的引用,后期赋值.
三级缓存结构
/** Cache of singleton objects: bean name --> bean instance(缓存单例实例化对象的Map集合,value是就绪状态下的bean) 一级缓存*/
//如果是aop,则是代理对象
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
/** Cache of early singleton objects: bean name --> bean instance(早期的单身对象缓存集合,value是只经过实例化,但是没有初始化的bean) 二级缓存*/
//如果是aop,则是代理对象
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
/** Cache of singleton factories: bean name --> ObjectFactory(单例的工厂Bean缓存集合) 三级缓存*/
//如果是aop,则会创建代理对象
private final Map<String, ObjectFactory> singletonFactories = new HashMap<String, ObjectFactory>(16);
一个含有循环依赖的bean加载主要流程
1.A.getSingleton(beanName)从三级缓存中获取,获取不到。
2.递归引入A的依赖。此时A还没有成员属性。
3.A.getSingleton(name,factory)去创建bean:crateBean().
4.createBean的时候,先实例化bean,然后把获取bean的beanFactory放进三级缓存。
5.填充A的属性,此时会B.getBean()。
6.B执行1-4步骤。
7.填充B的成员变量A。
8.这个时候,A.getSingleton(beanName)从三级缓存中获取,可以获取到A的提前引用。通过从三级缓存中获取的objectFactory,创建A的二级缓存对象,此时A只进行了实例化,没有初始化。
9.B完成属性赋值和初始化。
10.B将初始化好的bean放入一级缓存。
11.A将初始化好的B进行属性赋值,然后初始化。
12.A的bean放入一级缓存。
13.完成。
Bean的线程安全
spring里面的bean是线程安全的吗,比如@contrller,@service,@bean等生成的对象.
答:Spring里面的bean是线程不安全的.
说明:spring默认的注入方式是单例,即所有的对象都会生成一个.必然存在着资源竞争.但是spring又是怎么保证不会出现线程问题呢?
spring里面的bean都是无状态的,既然每个对象都没有状态,就不会存在线程问题了.
每个bean只存在着方法的调用,这部分是在虚拟机栈里面完成,jvm的虚拟机栈是线程安全的.因此不会存在线程问题.
需要注意的是,我们在每个bean里面也要遵循这种原则,bean里面不要写入变量,防止出现线程问题.
注意事项:
不要在@Controller/@Service等容器中变量,默认的单例是线程不安全的.
不要在@Controller/@Service等容器中定义静态变量,不论是单例(singleton)还是多实例(prototype)他都是线程不安全的.
如果要使用共享变量的话,使用threadLocal.
spring 只使用二级缓存可以解决循环依赖吗?
如果只使用二级缓存也是可以解决的,使用三级缓存的目的1是为了延迟实例化,2是为了更好的符合aop的设计原则:实例化,属性赋值,初始话,生成aop对象。如果只使用二级缓存,则会破坏这个原则。
Last updated
Was this helpful?