精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

玩轉Spring各種作用域Bean Scope及源碼分析

開發 前端
Spring Scope Bean是Spring框架中用于管理Bean的作用域的機制,它定義了Bean的生命周期和實例化策略。通過合理地選擇Bean的作用域,可以優化應用的性能和資源利用率。

環境:Spring5.3.23

一. 簡介

Spring Scope Bean是Spring用于管理Bean的作用域的一種機制。它定義了容器中Bean的生命周期和實例化策略,即如何創建Bean實例。

在Spring中,Bean的作用域包括單例(singleton)、原型(prototype)、請求(request)、會話(session)等。每個作用域都有其特定的使用場景和行為:

  1. 單例(singleton):這是Spring默認的作用域,表示在整個Spring容器中,只有一個Bean實例存在。無論你從哪個地方獲取這個Bean,都將返回同一個實例。
  2. 原型(prototype):每次從容器中請求Bean時,都會創建一個新的Bean實例。
  3. 請求(request):在一個HTTP請求的范圍內,Bean是單例的。這種作用域適用于與單個請求關聯的Bean。
  4. 會話(session):在一個HTTP會話的范圍內,Bean是單例的。這種作用域適用于與單個用戶會話關聯的Bean。

此外,Spring還提供了其他一些作用域應用(Application)、WebSocket,以滿足不同場景的需求。

通過合理地選擇Bean的作用域,可以優化應用的性能和資源利用率。例如,對于需要頻繁創建和銷毀實例的Bean,使用原型作用域會更高效;而對于需要在多個請求或會話之間共享狀態的Bean,則可以選擇單例或會話作用域。附官方圖:

圖片圖片

接下來將分別介紹每一種作用域bean。

二. 作用域應用

基礎類

static class Person {
  @Override
  public String toString() {
    return super.toString() + " - " + this.hashCode() + "" ;
  }
}

2.1 單例(singleton)

默認使用@Bean,@Service,@Controller注解標注的注解都是單例的。也可以同@Scope注解指定作用域為單例

@Bean
// 不指定@Scope默認就是單例
@Scope(value = "singleton")
public Person person() {
  return new Person() ;
}

測試

try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
  context.registerBean(Config.class) ;
  context.refresh() ;
  
  System.out.println(context.getBean(Person.class)) ;
  System.out.println(context.getBean(Person.class)) ;
}

控制臺輸出

com.pack.main.scope.ScopeMain5$Person@5e0e82ae - 1578009262
com.pack.main.scope.ScopeMain5$Person@5e0e82ae - 1578009262

每次獲取的都是同一個實例。

原理

public abstract class AbstractBeanFactory {
  protected <T> T doGetBean(...) {
    // ...
    // 判斷是否是單例
    if (mbd.isSingleton()) {
      // 先從單例池中查找是否已經存在,不存在則調用createBean創建,
      // 然后存入單例池中
      sharedInstance = getSingleton(beanName, () -> {
        try {
          return createBean(beanName, mbd, args);
        }
      });
    }
    // ...
  }
}

2.2 原型(prototype)

每次從容器中請求Bean時,都會創建一個新的Bean實例。

@Bean
@Scope(value = "prototype")
public Person person() {
  return new Person() ;
}

控制臺輸出

com.pack.main.scope.ScopeMain5$Person@fa4c865 - 262457445
com.pack.main.scope.ScopeMain5$Person@3bd82cf5 - 1004023029

每次獲取都是不同的對象。

原理

public abstract class AbstractBeanFactory {
  protected <T> T doGetBean(...) {
    // ...
    // 判斷是否是單例
    if (mbd.isSingleton()) {
      // ...
    }
    // 判斷是否是原型
    else if (mbd.isPrototype()) {
      Object prototypeInstance = null;
      try {
        // 不存在什么緩存池,直接創建bean實例返回
        prototypeInstance = createBean(beanName, mbd, args);
      }
    }
    // ...
  }
}

這里考慮一個問題,如何在單例bean中正確的注入原型bean?

2.3 請求(request)

接下來都是與web環境相關了,所以這里演示的示例會以SpringBoot3.0.5環境演示。

基礎類

@Component
@Scope(value = "request")
public class Person {
}

測試類

@RestController
@RequestMapping("/scopes")
public class ScopeController {
  @Resource
  private Person person ;
  @Resource
  private PersonService ps ;
  @GetMapping("/request")
  public Person request() {
    System.out.println("ScopeController: " + person) ;
    ps.query() ;
    return person ;
  }
}

Service

@Service
public class PersonService {
  @Resource
  private Person person ;
  public void query() {
    System.out.println("PersonService: " + person) ;
  }
}

如果上面這樣配置,啟動服務將會報錯:

Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
  at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131) ~[spring-web-6.0.7.jar:6.0.7]

該錯誤的原因就是你在一個單例bean中注入一個request作用域的bean,而request作用域bean的生命周期是在一個web請求開始創建的,所以這里你當然是沒法注入的。

解決辦法:

  • @Scope設置代理模式
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class Person {}

測試結果

ScopeController: com.pack.scopes.Person@106a9684 - 275420804
PersonService: com.pack.scopes.Person@106a9684 - 275420804
ScopeController: com.pack.scopes.Person@64396678 - 1681483384
PersonService: com.pack.scopes.Person@64396678 - 1681483384

每次請求接口都獲取的不是同一個實例。并且在一個完整的請求中獲取的Person都是同一個。

  • 使用@RequestScope

該注解原理與上面其實一致的

@Scope(WebApplicationContext.SCOPE_REQUEST)
public @interface RequestScope {
  @AliasFor(annotation = Scope.class)
  // 設置好了使用代理
  ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
}

2.4 會話(session)

@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
// 與request一樣,必須設置代理模式或者使用下面這個注解
// @SessionScope
public class Person {}

測試

ScopeController: com.pack.scopes.Person@2b56038d - 727057293
PersonService: com.pack.scopes.Person@2b56038d - 727057293
ScopeController: com.pack.scopes.Person@2b56038d - 727057293
PersonService: com.pack.scopes.Person@2b56038d - 727057293

多次訪問都是同一個session;你再換個瀏覽器訪問

ScopeController: com.pack.scopes.Person@1aa201fd - 446824957
PersonService: com.pack.scopes.Person@1aa201fd - 446824957
ScopeController: com.pack.scopes.Person@1aa201fd - 446824957
PersonService: com.pack.scopes.Person@1aa201fd - 446824957

此時對象就是一個新的了,不同的瀏覽器訪問當然不是同一個session了。

2.5 應用(application)

@Scope(value = "application", proxyMode = ScopedProxyMode.TARGET_CLASS)
// @ApplicationScope
// 都是web環境,所以情況都一樣
public class Person {}

測試

360瀏覽器

ScopeController: com.pack.scopes.Person@6371b4b6 - 1668396214
PersonService: com.pack.scopes.Person@6371b4b6 - 1668396214

Chrome瀏覽器

ScopeController: com.pack.scopes.Person@6371b4b6 - 1668396214
PersonService: com.pack.scopes.Person@6371b4b6 - 1668396214

他們是同一個對象,application作用域生命周期與整個應用一樣,只有你關閉了服務器,在啟動后才會是再重新創建的bean對象。

3. web作用域原理

3.1 注冊作用域

public abstract class AbstractApplicationContext {
  public void refresh() {
    postProcessBeanFactory(beanFactory);
  }
}
public class AnnotationConfigServletWebServerApplicationContext {
  protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    super.postProcessBeanFactory(beanFactory);
  }
}
public class ServletWebServerApplicationContext {
  protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // ...
    registerWebApplicationScopes();
  }
  private void registerWebApplicationScopes() {
    WebApplicationContextUtils.registerWebApplicationScopes(getBeanFactory());
  }
}
public abstract class WebApplicationContextUtils {
  public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) {
    registerWebApplicationScopes(beanFactory, null);
  }
  public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,
      @Nullable ServletContext sc) {
    // 注冊作用域
    beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
    beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());
    if (sc != null) {
      ServletContextScope appScope = new ServletContextScope(sc);
      beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);
    }
  }
}

這里每一種web作用域都有一個對應的Scope實現RequestScope,SessionScope,ServletContextScope。

3.2 查找web作用域bean

public abstract class AbstractBeanFactory {
  protected <T> T doGetBean(...) {
    // ...
    // 判斷是否是單例
    if (mbd.isSingleton()) {
      // ...
    }
    // 判斷是否是原型
    else if (mbd.isPrototype()) {
      Object prototypeInstance = null;
      try {
        // 不存在什么緩存池,直接創建bean實例返回
        prototypeInstance = createBean(beanName, mbd, args);
      }
    }
    // 其它作用域bean,如上面的web作用域
    else {
      String scopeName = mbd.getScope();
      Scope scope = this.scopes.get(scopeName);
      if (scope == null) {
        throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
      }
      try {
          // 通過具體Scope的實現類獲取bean對象
        Object scopedInstance = scope.get(beanName, () -> {
          beforePrototypeCreation(beanName);
          try {
            // 首次都還是會創建
            return createBean(beanName, mbd, args);
            }
          });
        }
      }
    }
    // ...
  }
}

總結:Spring Scope Bean是Spring框架中用于管理Bean的作用域的機制,它定義了Bean的生命周期和實例化策略。通過合理地選擇Bean的作用域,可以優化應用的性能和資源利用率。

責任編輯:武曉燕 來源: Spring全家桶實戰案例源碼
相關推薦

2021-07-05 08:43:46

Spring Beanscope作用域

2023-09-05 08:23:56

SpringScope方法

2011-03-18 09:27:00

Spring

2022-05-27 08:25:55

容器Spring

2024-01-29 08:28:01

Spring事務失效

2024-11-26 17:43:51

2024-11-14 14:53:04

2022-11-29 17:38:57

DockerfileARG作用域

2021-04-28 06:26:11

Spring Secu功能實現源碼分析

2023-06-29 08:32:41

Bean作用域

2010-08-25 15:19:20

DHCP作用域

2025-11-17 07:45:45

SpringBean接口

2016-12-19 11:10:32

JavaScript變量作用域

2023-10-07 09:16:55

SpringBoot啟動流程

2022-03-07 10:05:02

SpringStreamMQ連接

2021-06-02 07:02:42

js作用域函數

2022-08-31 07:04:50

Bean作用域

2021-08-09 11:15:28

MybatisJavaSpring

2012-02-23 12:53:40

JavaPlay Framew

2019-03-13 08:00:00

JavaScript作用域前端
點贊
收藏

51CTO技術棧公眾號

91精品入口蜜桃| 精品少妇一区二区三区视频免付费| 美乳视频一区二区| 青青草视频在线观看免费| 久久不卡国产精品一区二区| 日本精品一区二区三区四区的功能| 日韩亚洲视频| 国产手机精品视频| 国产日韩精品视频一区二区三区| 亚洲天堂久久av| 国产精品自拍视频在线| 日韩影视在线| 久久久久久麻豆| 欧美在线影院在线视频| 国产欧美一区二区三区不卡高清| 国产黄色片免费看| 日韩精品dvd| 欧美videofree性高清杂交| 免费观看精品视频| www.在线视频| 久久蜜桃av一区二区天堂| 国产日韩在线看| 欧美精品亚洲精品日韩精品| 久久一区91| 日韩经典中文字幕在线观看| 国产亚洲视频一区| 韩国主播福利视频一区二区三区| 最新国产成人在线观看| 久久精品五月婷婷| 国产成人三级在线播放| 久久综合激情| 久久久久久久一| 永久免费看片视频教学| 香蕉久久精品日日躁夜夜躁| 一区二区三区免费观看| 日韩欧美精品一区二区| 亚洲精品一区二区口爆| 免费高清成人在线| 777午夜精品福利在线观看| 在线看的片片片免费| 国产精品一区二区99| 欧美精品一区二区三区很污很色的 | 久久一夜天堂av一区二区三区| 亚洲专区在线视频| 在线观看你懂的网站| 亚洲综合电影一区二区三区| 久久久女人电视剧免费播放下载| 四虎精品免费视频| 手机在线电影一区| 中文字幕精品久久久久| japanese中文字幕| 久久99影视| 亚洲欧美国产日韩中文字幕| 亚洲熟女乱综合一区二区三区| 日韩av综合| 日韩一级大片在线| 中文字幕55页| 免费观看亚洲天堂| 7799精品视频| 肉色超薄丝袜脚交| 久久69av| 精品毛片乱码1区2区3区| 成人三级做爰av| 亚洲一区二区免费在线观看| 欧美一卡在线观看| 亚洲AV无码久久精品国产一区| а天堂中文最新一区二区三区| 欧美顶级少妇做爰| 激情成人在线观看| 视频欧美一区| 日韩视频在线一区二区| 亚洲精品久久一区二区三区777| 91欧美极品| 亚洲精品久久7777777| 人妻熟女aⅴ一区二区三区汇编| 亚欧洲精品视频在线观看| 亚洲美女性视频| 国产精品密蕾丝袜| 日韩欧美中文| 九九精品在线视频| 国产乡下妇女做爰视频| 免费久久99精品国产自在现线| 日本亚洲欧洲色| 在线视频1卡二卡三卡| 国产一区高清在线| 成人影片在线播放| 日韩porn| 亚洲欧洲成人av每日更新| 欧美另类videosbestsex日本| 成人超碰在线| 色乱码一区二区三区88| theporn国产精品| 国偷自产视频一区二区久| 亚洲码在线观看| 永久av免费网站| 亚洲日韩视频| 国产精品欧美激情在线播放| www.av黄色| 国产午夜久久久久| 国产亚洲精品久久久久久久| 亚洲精品永久免费视频| 欧美二区三区91| 中文字幕av观看| 久久久精品久久久久久96| 97精品国产97久久久久久春色| 中文字幕av资源| 大尺度一区二区| 亚洲欧美电影在线观看| 激情av在线| 在线观看av一区二区| 日韩精品xxx| 波多野结衣在线播放一区| 欧美激情喷水视频| 中文无码av一区二区三区| 成人免费视频免费观看| 亚洲一区二区三区免费观看| 黄色在线网站噜噜噜| 欧美午夜理伦三级在线观看| 欧产日产国产精品98| 91嫩草亚洲精品| 欧美最猛性xxxxx(亚洲精品)| 超碰在线观看av| 国产精品伦理一区二区| 国产免费成人在线| 综合久久成人| 久久综合色影院| 中文字幕欧美色图| 久久亚洲一区二区三区四区| 日韩精品一区二区三区四| 婷婷久久综合九色综合99蜜桃| 亚洲精品视频播放| 久一视频在线观看| 国产精品传媒精东影业在线| 91精品国产高清久久久久久| 精品女同一区二区三区| 国产精品美女久久久久高潮| 午夜肉伦伦影院| 天堂日韩电影| 久久免费视频在线观看| 国产精品玖玖玖| 中文字幕av资源一区| 动漫av免费观看| 亚洲精华一区二区三区| 4p变态网欧美系列| 无码国产精品高潮久久99| 亚洲自拍另类综合| 亚洲精品久久久久久| 综合色一区二区| 成人激情av在线| 1769在线观看| 欧美日韩综合在线| 欧日韩不卡视频| 美女脱光内衣内裤视频久久影院| 日韩欧美视频第二区| 色香欲www7777综合网| 亚洲三级黄色在线观看| 欧美成人一区二区三区四区| 久久久久国色av免费看影院| 日韩久久一级片| 伊人久久大香线蕉av不卡| 欧美亚洲国产日韩2020| 青青青草原在线| 色欧美乱欧美15图片| 国产毛片欧美毛片久久久| 日韩精品久久理论片| 婷婷四月色综合| 日韩久久一区| 欧美日本高清一区| 丰满少妇一级片| 精品人伦一区二区三区蜜桃网站 | 久久久亚洲午夜电影| 日日碰狠狠躁久久躁婷婷| 精品视频国产| 91久久精品国产| 国精一区二区三区| 国产午夜精品麻豆| 一区二区三区午夜| 亚洲综合图片区| 亚洲天堂网一区二区| 日本伊人午夜精品| 亚洲小说欧美另类激情| 99久久香蕉| 日韩av电影中文字幕| 午夜视频在线观看网站| 欧美精品乱人伦久久久久久| 久久久全国免费视频| 久久综合久久综合九色| 天天干天天爽天天射| 欧美日韩国产一区精品一区| 久久99精品久久久久久久久久| а√天堂资源国产精品| 欧美成人一区二区三区电影| 涩涩视频在线观看免费| 欧美日韩免费观看一区二区三区| 麻豆亚洲av成人无码久久精品| 91小视频免费看| 视频在线观看免费高清| 激情综合电影网| 天堂社区 天堂综合网 天堂资源最新版 | 国产又粗又猛又爽又黄| 可以看av的网站久久看| 久久精品在线免费视频| 美女毛片一区二区三区四区最新中文字幕亚洲| 国产精品久久久久77777| 人人澡人人添人人爽一区二区| 亚洲深夜福利在线| 亚洲国产精品久久久久爰性色| 色成年激情久久综合| 免费视频网站www| 欧美韩国一区二区| 亚洲黄色小说在线观看| 喷水一区二区三区| 成人在线观看你懂的| 波多野结衣的一区二区三区| 精品国产一区二区三区麻豆免费观看完整版 | 亚洲私人黄色宅男| 中文字幕第4页| 成人动漫中文字幕| 亚洲国产午夜精品| 日韩经典中文字幕一区| 妞干网在线观看视频| 天天射天天综合网| 日本10禁啪啪无遮挡免费一区二区 | seseavlu视频在线| 亚洲精品乱码久久久久久金桔影视 | 亚洲一卡久久| 女人色极品影院| 亚洲精品在线观看91| 奇米视频888战线精品播放| 超碰97久久国产精品牛牛| 成人午夜两性视频| 成人在线网站| 日韩美女福利视频| 日本黄色免费在线| 国语自产精品视频在线看一大j8| a级在线观看| 久久人体大胆视频| 欧美日韩在线资源| 中文字幕不卡在线视频极品| 国产裸舞福利在线视频合集| 亚洲欧美一区二区激情| 五月婷婷在线观看视频| 亚洲高清不卡av| 亚洲精品久久久久久动漫器材一区| 在线成人免费观看| 国产又粗又猛又色又| 欧美色男人天堂| 性高潮视频在线观看| 在线观看av不卡| 色老头在线视频| 在线影院国内精品| 国产男人搡女人免费视频| 91福利在线导航| 中国一区二区视频| 欧美一a一片一级一片| 成人黄色免费网| 欧美日韩一二三| 国产精品欧美亚洲| 日韩一级高清毛片| 亚洲成人中文字幕在线| 精品国产乱码久久| 性感美女一级片| 亚洲视频第一页| 一区二区三区视频在线观看视频| 日韩小视频在线| 在线观看免费视频你懂的| 色综合视频一区中文字幕| 成年人视频免费在线播放| 91av视频在线观看| 午夜精品成人av| 国产美女高潮久久白浆| 国产成年精品| 风间由美久久久| 午夜先锋成人动漫在线| 亚洲高清在线观看一区| 91精品综合| 国产九九九九九| 日本女人一区二区三区| 青娱乐精品在线| 成人高清免费观看| 日本二区在线观看| 亚洲视频一二区| 日韩av大片在线观看| 欧美午夜精品久久久久久孕妇| 国产一区二区波多野结衣 | 天堂网在线播放| 亚洲天堂成人在线视频| 成人a在线视频免费观看| 午夜精品美女自拍福到在线| 91伊人久久| 国产精品国产精品| 欧美综合另类| 国产欧美日韩小视频| 全部av―极品视觉盛宴亚洲| 日本少妇xxx| 国产婷婷色一区二区三区| 久久国产美女视频| 欧美日韩综合视频| 国产情侣自拍小视频| 亚洲欧美日韩图片| 成人在线免费看片| 91成人国产在线观看| 国产精品天堂蜜av在线播放 | 在线观看国产一级片| kk眼镜猥琐国模调教系列一区二区| 国产精品成人无码免费| 亚洲午夜电影在线| 亚洲视频一区在线播放| 日韩精品中文字| 午夜在线激情影院| 国产精品欧美一区二区三区奶水| 国产极品模特精品一二| 亚洲一区二区三区精品动漫| 久久精品日韩欧美| 四虎永久免费观看| 自拍偷拍国产精品| 怡红院av久久久久久久| 亚洲成人久久一区| 日韩精品毛片| 国产精品成人播放| 日本天堂一区| 福利在线一区二区| 激情文学综合丁香| 少妇愉情理伦三级| 色婷婷国产精品综合在线观看| 黄色av中文字幕| 欧美不卡视频一区发布| 国产美女久久| 日韩亚洲欧美精品| 老司机精品视频网站| 日韩成人av一区二区| 亚洲图片自拍偷拍| 国产成年妇视频| 久久视频精品在线| 成人精品在线| 中文字幕中文字幕99| 美女视频一区二区三区| 91网站免费入口| 色综合久久中文字幕综合网| 香蕉国产在线视频| 韩剧1988免费观看全集| 亚洲日本一区二区三区在线| 一本色道久久88亚洲精品综合| 久久99精品国产麻豆不卡| 黄大色黄女片18免费| 欧美日韩色综合| 幼a在线观看| 国产欧美日韩中文字幕| 欧美xxav| 伊人五月天婷婷| 亚洲免费资源在线播放| 国产三级小视频| 免费91在线视频| 亚洲精品观看| 日韩人妻无码精品久久久不卡| 东方aⅴ免费观看久久av| 精品无码m3u8在线观看| 亚洲第一级黄色片| 国产高清自产拍av在线| 欧美日韩在线播放一区二区| 日本不卡在线视频| jizzjizzjizz国产| 欧美精品亚洲一区二区在线播放| 国产美女在线观看| 99在线视频免费观看| 亚洲三级电影在线观看| 亚洲精品视频久久久| 欧美群妇大交群的观看方式| 黄色免费网站在线| 成人h在线播放| 国产欧美精品| 刘亦菲国产毛片bd| 欧美一区二区精品在线| 国产亚av手机在线观看| 六月婷婷久久| 免费看欧美女人艹b| 欧美做爰爽爽爽爽爽爽| 亚洲成人激情在线观看| 成人免费无遮挡| 中国成人在线视频| 粉嫩aⅴ一区二区三区四区| 五月婷婷开心网| 色偷偷综合社区| 波多野结衣欧美| www.激情小说.com| 有坂深雪av一区二区精品| 亚洲欧美日韩动漫| 国产三级精品网站| 99国产精品私拍| 波多野结衣欲乱| 亚洲午夜三级在线| 日本护士...精品国| 国产免费亚洲高清| 激情久久五月| 国产在线综合视频| 亚洲国产成人久久| 久久人体av| 国产成人无码a区在线观看视频| 国产精品每日更新| 日韩一卡二卡在线|