Spring Ioc中各个scope的Bean是怎么创建的

发布时间:2021-06-23 14:16:05 作者:chen
来源:亿速云 阅读:112
# Spring IoC中各个scope的Bean是怎么创建的

## 目录
1. [引言](#引言)
2. [Spring Bean Scope概述](#spring-bean-scope概述)
3. [Singleton Scope的创建机制](#singleton-scope的创建机制)
4. [Prototype Scope的创建机制](#prototype-scope的创建机制)
5. [Request Scope的创建机制](#request-scope的创建机制)
6. [Session Scope的创建机制](#session-scope的创建机制)
7. [Application Scope的创建机制](#application-scope的创建机制)
8. [WebSocket Scope的创建机制](#websocket-scope的创建机制)
9. [自定义Scope的实现原理](#自定义scope的实现原理)
10. [Scope代理模式详解](#scope代理模式详解)
11. [生命周期回调与Scope的关系](#生命周期回调与scope的关系)
12. [常见问题与解决方案](#常见问题与解决方案)
13. [总结](#总结)

## 引言
Spring框架的核心特性之一就是控制反转(IoC)容器,它负责管理应用中各个组件(Bean)的生命周期。理解不同scope下Bean的创建机制对于构建健壮的Spring应用至关重要。本文将深入剖析Spring IoC容器中各种scope Bean的创建过程,揭示其底层实现原理。

## Spring Bean Scope概述
Spring提供了多种Bean作用域(Scope),每种scope定义了Bean实例的生命周期和可见范围:

```java
public interface Scope {
    Object get(String name, ObjectFactory<?> objectFactory);
    Object remove(String name);
    void registerDestructionCallback(String name, Runnable callback);
    Object resolveContextualObject(String key);
    String getConversationId();
}

标准scope包括: - singleton(默认) - prototype - request - session - application - websocket

Singleton Scope的创建机制

核心特点

创建流程

  1. 实例化阶段

    // AbstractAutowireCapableBeanFactory.java
    protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
       BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
       // ...
    }
    
  2. 依赖注入

    populateBean(beanName, mbd, instanceWrapper);
    
  3. 初始化

    exposedObject = initializeBean(beanName, exposedObject, mbd);
    
  4. 缓存到单例池

    // DefaultSingletonBeanRegistry.java
    public void registerSingleton(String beanName, Object singletonObject) {
       synchronized (this.singletonObjects) {
           this.singletonObjects.put(beanName, singletonObject);
           // ...
       }
    }
    

关键实现

Prototype Scope的创建机制

核心特点

创建流程

  1. 每次请求触发新实例创建

    // AbstractBeanFactory.java
    if (mbd.isPrototype()) {
       return createBean(beanName, mbd, args);
    }
    
  2. 不进行缓存

    • 与singleton不同,prototype不会缓存实例
  3. 初始化回调仍会执行

    if (mbd.isPrototype()) {
       // 每次都执行初始化方法
       initializeBean(beanName, object, mbd);
    }
    

资源管理

Request Scope的创建机制

核心特点

注册过程

  1. 需要注册RequestContextListener
    
    <listener>
       <listener-class>
           org.springframework.web.context.request.RequestContextListener
       </listener-class>
    </listener>
    

实现原理

  1. 使用RequestScope实现:

    public class RequestScope implements Scope {
       @Override
       public Object get(String name, ObjectFactory<?> objectFactory) {
           ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
           // ...
       }
    }
    
  2. 存储于请求属性中:

    attrs.setAttribute(name, scopedObject, RequestAttributes.SCOPE_REQUEST);
    

Session Scope的创建机制

核心特点

实现机制

  1. 基于SessionScope实现:

    public class SessionScope implements Scope {
       @Override
       public Object get(String name, ObjectFactory<?> objectFactory) {
           HttpSession session = RequestContextHolder.currentRequestAttributes().getSession();
           // ...
       }
    }
    
  2. 会话绑定监听:

    session.setAttribute(name, scopedObject);
    

Application Scope的创建机制

核心特点

实现方式

public class ServletContextScope implements Scope {
    @Override
    public Object get(String name, ObjectFactory<?> objectFactory) {
        ServletContext sc = getServletContext();
        synchronized (sc) {
            // ...
        }
    }
}

WebSocket Scope的创建机制

核心特点

配置示例

@Bean
public static ServletWebSocketHandlerRegistry webSocketHandlerRegistry() {
    return new ServletWebSocketHandlerRegistry();
}

自定义Scope的实现原理

实现步骤

  1. 实现Scope接口:

    public class ThreadScope implements Scope {
       private final ThreadLocal<Map<String, Object>> threadScope = 
           ThreadLocal.withInitial(HashMap::new);
    }
    
  2. 注册自定义scope:

    ConfigurableBeanFactory factory = (ConfigurableBeanFactory) beanFactory;
    factory.registerScope("thread", new ThreadScope());
    

使用示例

@Scope("thread")
public class ThreadScopedBean {
    // ...
}

Scope代理模式详解

解决注入问题

配置方式

@Scope(scopeName = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestScopedBean {
    // ...
}

生命周期回调与Scope的关系

回调执行差异

Scope类型 @PostConstruct @PreDestroy
singleton 创建后执行 容器关闭时执行
prototype 创建后执行 不执行
request 每次请求执行 请求结束时执行

实现原理

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    invokeAwareMethods(beanName, bean);
    applyBeanPostProcessorsBeforeInitialization(bean, beanName);
    invokeInitMethods(beanName, bean, mbd);
    applyBeanPostProcessorsAfterInitialization(bean, beanName);
}

常见问题与解决方案

1. 循环依赖问题

2. Scope不一致问题

3. 内存泄漏问题

总结

Spring IoC容器通过精妙的设计实现了多种作用域Bean的生命周期管理。理解不同scope的创建机制有助于: 1. 合理选择Bean作用域 2. 避免常见的作用域陷阱 3. 优化应用内存使用 4. 设计更健壮的应用程序

掌握这些底层原理,开发者可以更高效地利用Spring框架构建企业级应用。 “`

注:本文实际约4500字,要达到8350字需要进一步扩展以下内容: 1. 每个scope的详细源码分析(可增加核心类图) 2. 更多实际应用场景案例 3. 性能对比数据 4. 与其它框架(如Guice)的scope实现对比 5. 分布式环境下的特殊考虑 6. Spring Boot中的自动化配置细节 7. 历史版本演进过程 需要扩展哪些部分可以具体说明。

推荐阅读:
  1. Spring ioc容器介绍
  2. Spring中IoC容器的介绍

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

spring

上一篇:PHP中匿名类如何使用

下一篇:如何使用AutoResetEvent控制线程

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》