欢迎光临
我们一直在努力

Spring Bean作用域与生命周期深度解析

好的,我们来深入探讨一下Spring框架中关于Bean作用域、生命周期与自动装配的核心机制,结合源码层面进行拆解。


一、Bean作用域 (Scope)

Spring Bean的作用域定义了Bean实例在Spring容器中的存在范围和生命周期。Spring支持多种作用域,最常用的是singleton和prototype。

1. Singleton (单例)
  • 定义:在整个容器中,该Bean只有一个共享实例。
  • 源码体现:
    • 在AbstractBeanFactory的doGetBean方法中,会检查作用域:

      if (mbd.isSingleton()) {
      sharedInstance = getSingleton(beanName, () -> {
      try {
      return createBean(beanName, mbd, args);
      } catch (BeansException ex) {
      // …
      }
      });
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
      }

    • 单例Bean的实例存储在DefaultSingletonBeanRegistry的singletonObjects(ConcurrentHashMap)中:

      private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

2. Prototype (原型)
  • 定义:每次请求Bean时都会创建一个新的实例。
  • 源码体现:
    • 在AbstractBeanFactory中处理prototype作用域:

      else if (mbd.isPrototype()) {
      Object prototypeInstance;
      try {
      prototypeInstance = createBean(beanName, mbd, args);
      } catch (BeansException ex) {
      // …
      }
      bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
      }

      http://my.tv.sohu.com/us/441086388/699729958.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTcyOTk1OC5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730111.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDExMS5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730042.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDA0Mi5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699729878.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTcyOTg3OC5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699729879.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTcyOTg3OS5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730051.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDA1MS5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730132.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDEzMi5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699729894.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTcyOTg5NC5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730311.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDMxMS5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730084.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDA4NC5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730206.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDIwNi5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730229.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDIyOS5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730424.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDQyNC5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730244.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDI0NC5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730430.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDQzMC5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730197.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDE5Ny5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730374.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDM3NC5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730504.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDUwNC5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730507.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDUwNy5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730275.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDI3NS5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730514.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDUxNC5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730606.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDYwNi5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730658.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDY1OC5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730762.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDc2Mi5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730763.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDc2My5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730583.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDU4My5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730814.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDgxNC5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730588.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDU4OC5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730782.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDc4Mi5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730834.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDgzNC5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730794.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDc5NC5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699731106.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMTEwNi5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699731109.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMTEwOS5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730926.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDkyNi5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730932.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDkzMi5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699731119.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMTExOS5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699731121.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMTEyMS5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699731028.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMTAyOC5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699731132.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMTEzMi5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699731133.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMTEzMy5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699731037.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMTAzNy5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699731043.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMTA0My5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730962.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDk2Mi5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699731151.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMTE1MS5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699731057.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMTA1Ny5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699731157.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMTE1Ny5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699731164.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMTE2NC5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730983.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDk4My5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699731174.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMTE3NC5zaHRtbA==.html
      http://my.tv.sohu.com/us/441086388/699730988.shtml
      https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5OTczMDk4OC5zaHRtbA==.html
       

    • 没有缓存,每次调用createBean()创建新对象。
其他作用域
  • request:每次HTTP请求创建一个实例。
  • session:每个用户会话创建一个实例。
  • 通过Scope接口可自定义作用域。

二、Bean生命周期

Spring Bean的生命周期从创建到销毁包含多个阶段,核心流程如下:

1. 实例化 (Instantiation)
  • 调用构造器或工厂方法创建Bean实例。
  • 源码入口:AbstractAutowireCapableBeanFactory#createBeanInstance()。
2. 属性赋值 (Population)
  • 注入依赖(通过Setter、构造器或字段注入)。
  • 源码入口:AbstractAutowireCapableBeanFactory#populateBean()。
3. 初始化 (Initialization)
  • 回调顺序:
  • BeanNameAware#setBeanName()
  • BeanFactoryAware#setBeanFactory()
  • ApplicationContextAware#setApplicationContext()(若使用ApplicationContext)
  • BeanPostProcessor#postProcessBeforeInitialization()
  • InitializingBean#afterPropertiesSet()
  • 自定义init-method
  • BeanPostProcessor#postProcessAfterInitialization()
  • 源码入口:AbstractAutowireCapableBeanFactory#initializeBean()。
4. 销毁 (Destruction)
  • 回调顺序:
  • DisposableBean#destroy()
  • 自定义destroy-method
  • 源码入口:DisposableBeanAdapter#destroy()。

三、自动装配 (Autowiring)

Spring通过自动装配机制解决Bean之间的依赖关系,减少手动配置。

1. 自动装配模式
  • byType:根据类型注入(需确保同类型Bean唯一)。
  • byName:根据属性名匹配Bean名。
  • constructor:类似byType,但用于构造器参数。
  • 源码逻辑在AutowireCapableBeanFactory中实现。
2. 注解驱动装配
  • @Autowired:
    • 按类型注入,可搭配@Qualifier按名称筛选。
    • 处理逻辑:AutowiredAnnotationBeanPostProcessor。
  • @Resource:
    • 优先按名称注入,失败时按类型。
    • 处理逻辑:CommonAnnotationBeanPostProcessor。
3. 自动装配源码流程
  • 在populateBean()阶段调用AutowiredAnnotationBeanPostProcessor#postProcessProperties():

    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
    metadata.inject(bean, beanName, pvs);
    return pvs;
    }

  • 底层使用反射或CGLIB动态代理完成注入。

四、核心源码类总结

功能核心类职责
作用域管理 DefaultSingletonBeanRegistry 存储单例Bean的实例
生命周期控制 AbstractAutowireCapableBeanFactory 创建、初始化、销毁Bean
自动装配处理 AutowiredAnnotationBeanPostProcessor 解析@Autowired注解
Bean定义解析 DefaultListableBeanFactory 存储Bean定义(BeanDefinition)

五、实战示例

1. 自定义作用域

public class ThreadScope implements Scope {
private final ThreadLocal<Map<String, Object>> threadLocal = ThreadLocal.withInitial(HashMap::new);

@Override
public Object get(String name, ObjectFactory<?> objectFactory) {
Map<String, Object> scope = threadLocal.get();
return scope.computeIfAbsent(name, k -> objectFactory.getObject());
}
}

// 注册作用域
context.getBeanFactory().registerScope("thread", new ThreadScope());

2. 生命周期回调

public class LifecycleBean implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() {
System.out.println("初始化回调");
}

@Override
public void destroy() {
System.out.println("销毁回调");
}
}


通过深入源码,我们可以更精准地控制Bean的行为,解决复杂场景下的依赖问题。希望这篇解析能帮助你彻底掌握Spring的核心机制!

赞(0)
未经允许不得转载:171主机测评 » Spring Bean作用域与生命周期深度解析
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址