最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

如何在Spring中自定義scope的方法示例

 更新時間:2019年02月15日 11:03:31   作者:waylau  
這篇文章主要介紹了如何在Spring中自定義scope的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

大家對于 Spring 的 scope 應(yīng)該都不會默認(rèn)。所謂 scope,字面理解就是“作用域”、“范圍”,如果一個 bean 的 scope 配置為 singleton,則從容器中獲取 bean 返回的對象都是相同的;如果 scope 配置為prototype,則每次返回的對象都不同。

一般情況下,Spring 提供的 scope 都能滿足日常應(yīng)用的場景。但如果你的需求極其特殊,則本文所介紹自定義 scope 合適你。

Spring 內(nèi)置的 scope

默認(rèn)時,所有 Spring bean 都是的單例的,意思是在整個 Spring 應(yīng)用中,bean的實例只有一個??梢栽?bean 中添加 scope 屬性來修改這個默認(rèn)值。scope 屬性可用的值如下:

范圍 描述
singleton 每個 Spring 容器一個實例(默認(rèn)值)
prototype 允許 bean 可以被多次實例化(使用一次就創(chuàng)建一個實例)
request 定義 bean 的 scope 是 HTTP 請求。每個 HTTP 請求都有自己的實例。只有在使用有 Web 能力的 Spring 上下文時才有效
session 定義 bean 的 scope 是 HTTP 會話。只有在使用有 Web 能力的 Spring ApplicationContext 才有效
application 定義了每個 ServletContext 一個實例
websocket 定義了每個 WebSocket 一個實例。只有在使用有 Web 能力的 Spring ApplicationContext 才有效

如果上述 scope 仍然不能滿足你的需求,Spring 還預(yù)留了接口,允許你自定義 scope。

Scope 接口

org.springframework.beans.factory.config.Scope接口用于定義scope的行為:

package org.springframework.beans.factory.config;

import org.springframework.beans.factory.ObjectFactory;
import org.springframework.lang.Nullable;

public interface Scope {

 Object get(String name, ObjectFactory<?> objectFactory);

 @Nullable
 Object remove(String name);

 void registerDestructionCallback(String name, Runnable callback);

 @Nullable
 Object resolveContextualObject(String key);

 @Nullable
 String getConversationId();

}

一般來說,只需要重新 get 和 remove 方法即可。

自定義線程范圍內(nèi)的scope

現(xiàn)在進(jìn)入實戰(zhàn)環(huán)節(jié)。我們要自定義一個Spring沒有的scope,該scope將bean的作用范圍限制在了線程內(nèi)。即,相同線程內(nèi)的bean是同個對象,跨線程則是不同的對象。

1. 定義scope

要自定義一個Spring的scope,只需實現(xiàn) org.springframework.beans.factory.config.Scope接口。代碼如下:

package com.waylau.spring.scope;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;

/**
 * Thread Scope.
 * 
 * @since 1.0.0 2019年2月13日
 * @author <a  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Way Lau</a>
 */
public class ThreadScope implements Scope {
 
 private final ThreadLocal<Map<String, Object>> threadLoacal = new ThreadLocal<Map<String, Object>>() {
 @Override
 protected Map<String, Object> initialValue() {
  return new HashMap<String, Object>();
 }
 };

 public Object get(String name, ObjectFactory<?> objectFactory) {
 Map<String, Object> scope = threadLoacal.get();
 Object obj = scope.get(name);

 // 不存在則放入ThreadLocal
 if (obj == null) {
  obj = objectFactory.getObject();
  scope.put(name, obj);
  
  System.out.println("Not exists " + name + "; hashCode: " + obj.hashCode());
 } else {
  System.out.println("Exists " + name + "; hashCode: " + obj.hashCode());
 }

 return obj;
 }

 public Object remove(String name) {
 Map<String, Object> scope = threadLoacal.get();
 return scope.remove(name);
 }

 public String getConversationId() {
 return null;
 }

 public void registerDestructionCallback(String arg0, Runnable arg1) {
 }

 public Object resolveContextualObject(String arg0) {
 return null;
 }

}

在上述代碼中,threadLoacal用于做線程之間的數(shù)據(jù)隔離。換言之,threadLoacal實現(xiàn)了相同的線程相同名字的bean是同一個對象;不同的線程的相同名字的bean是不同的對象。

同時,我們將對象的hashCode打印了出來。如果他們是相同的對象,則hashCode是相同的。

2. 注冊scope

定義一個AppConfig配置類,將自定義的scope注冊到容器中去。代碼如下:

package com.waylau.spring.scope;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.config.CustomScopeConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * App Config.
 *
 * @since 1.0.0 2019年2月13日
 * @author <a  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Way Lau</a>
 */
@Configuration
@ComponentScan
public class AppConfig {

 @Bean
 public static CustomScopeConfigurer customScopeConfigurer() {
 CustomScopeConfigurer customScopeConfigurer = new CustomScopeConfigurer();

 Map<String, Object> map = new HashMap<String, Object>();
 map.put("threadScope", new ThreadScope());

 // 配置scope
 customScopeConfigurer.setScopes(map);
 return customScopeConfigurer;
 }
}

“threadScope”就是自定義ThreadScope的名稱。

3. 使用scope

接下來就根據(jù)一般的scope的用法,來使用自定義的scope了。代碼如下:

package com.waylau.spring.scope.service;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

/**
 * Message Service Impl.
 * 
 * @since 1.0.0 2019年2月13日
 * @author <a  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Way Lau</a>
 */
@Scope("threadScope")
@Service
public class MessageServiceImpl implements MessageService {
 
 public String getMessage() {
 return "Hello World!";
 }

}

其中@Scope("threadScope")中的“threadScope”就是自定義ThreadScope的名稱。

4. 定義應(yīng)用入口

定義Spring應(yīng)用入口:

package com.waylau.spring.scope;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.waylau.spring.scope.service.MessageService;

/**
 * Application Main.
 * 
 * @since 1.0.0 2019年2月13日
 * @author <a  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Way Lau</a>
 */
public class Application {

 public static void main(String[] args) {
 @SuppressWarnings("resource")
 ApplicationContext context = 
      new AnnotationConfigApplicationContext(AppConfig.class);

 MessageService messageService = context.getBean(MessageService.class);
 messageService.getMessage();
 
 MessageService messageService2 = context.getBean(MessageService.class);
 messageService2.getMessage();
 
 }

}

運行應(yīng)用觀察控制臺輸出如下:

Not exists messageServiceImpl; hashCode: 2146338580
Exists messageServiceImpl; hashCode: 2146338580

輸出的結(jié)果也就驗證了ThreadScope“相同的線程相同名字的bean是同一個對象”。

如果想繼續(xù)驗證ThreadScope“不同的線程的相同名字的bean是不同的對象”,則只需要將Application改造為多線程即可。

package com.waylau.spring.scope;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.waylau.spring.scope.service.MessageService;

/**
 * Application Main.
 * 
 * @since 1.0.0 2019年2月13日
 * @author <a  rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >Way Lau</a>
 */
public class Application {

 public static void main(String[] args) throws InterruptedException, ExecutionException {
 @SuppressWarnings("resource")
 ApplicationContext context = 
  new AnnotationConfigApplicationContext(AppConfig.class);

 CompletableFuture<String> task1 = CompletableFuture.supplyAsync(()->{
      //模擬執(zhí)行耗時任務(wù)
      MessageService messageService = context.getBean(MessageService.class);
  messageService.getMessage();
 
  MessageService messageService2 = context.getBean(MessageService.class);
  messageService2.getMessage();
      //返回結(jié)果
      return "result";
    });
 
 CompletableFuture<String> task2 = CompletableFuture.supplyAsync(()->{
      //模擬執(zhí)行耗時任務(wù)
      MessageService messageService = context.getBean(MessageService.class);
  messageService.getMessage();
 
  MessageService messageService2 = context.getBean(MessageService.class);
  messageService2.getMessage();
      //返回結(jié)果
      return "result";
    });
 
 task1.get();
 task2.get(); 
 
 }
}

觀察輸出結(jié)果;

Not exists messageServiceImpl; hashCode: 1057328090
Not exists messageServiceImpl; hashCode: 784932540
Exists messageServiceImpl; hashCode: 1057328090
Exists messageServiceImpl; hashCode: 784932540

上述結(jié)果驗證ThreadScope“相同的線程相同名字的bean是同一個對象;不同的線程的相同名字的bean是不同的對象”

源碼

https://github.com/waylau/spring-5-book 的 s5-ch02-custom-scope-annotation項目。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java?Web項目中如何添加Tomcat的Servlet-api.jar包(基于IDEA)

    Java?Web項目中如何添加Tomcat的Servlet-api.jar包(基于IDEA)

    servlet-api.jar是在編寫servlet必須用到的jar包下面這篇文章主要給大家介紹了基于IDEAJava?Web項目中如何添加Tomcat的Servlet-api.jar包的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-04-04
  • 基于SpringBoot?Mock單元測試詳解

    基于SpringBoot?Mock單元測試詳解

    這篇文章主要介紹了基于SpringBoot?Mock單元測試詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 應(yīng)用市場中Java攔截器和切面的使用實例詳解

    應(yīng)用市場中Java攔截器和切面的使用實例詳解

    這篇文章主要介紹了應(yīng)用市場中Java攔截器和切面的使用實例詳解,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01
  • Java 實戰(zhàn)項目錘煉之校園宿舍管理系統(tǒng)的實現(xiàn)流程

    Java 實戰(zhàn)項目錘煉之校園宿舍管理系統(tǒng)的實現(xiàn)流程

    讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+jsp+javaweb+mysql+ajax實現(xiàn)一個校園宿舍管理系統(tǒng),大家可以在過程中查缺補漏,提升水平
    2021-11-11
  • Java使用redisson實現(xiàn)分布式鎖的示例詳解

    Java使用redisson實現(xiàn)分布式鎖的示例詳解

    這篇文章主要為大家詳細(xì)介紹了在Java項目中使用redisson實現(xiàn)分布式鎖,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價值,需要的可以參考一下
    2023-07-07
  • Spring Boot中配置定時任務(wù)、線程池與多線程池執(zhí)行的方法

    Spring Boot中配置定時任務(wù)、線程池與多線程池執(zhí)行的方法

    這篇文章主要給大家介紹了關(guān)于Spring Boot中配置定時任務(wù)、線程池與多線程池執(zhí)行的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Nacos作為配置中心注冊監(jiān)聽器方法

    Nacos作為配置中心注冊監(jiān)聽器方法

    本文主要討論Nacos作為配置中心時,其中配置內(nèi)容發(fā)生更改時,我們的應(yīng)用程序能夠做的事。一般使用監(jiān)聽器來實現(xiàn)這步操作,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-02-02
  • Spring實戰(zhàn)之ResourceLoaderAware加載資源用法示例

    Spring實戰(zhàn)之ResourceLoaderAware加載資源用法示例

    這篇文章主要介紹了Spring實戰(zhàn)之ResourceLoaderAware加載資源用法,結(jié)合實例形式分析了spring使用ResourceLoaderAware加載資源相關(guān)配置與操作技巧,需要的朋友可以參考下
    2020-01-01
  • Java 高精度的大數(shù)字運算方式

    Java 高精度的大數(shù)字運算方式

    這篇文章主要介紹了Java 高精度的大數(shù)字運算方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之KMP算法

    Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之KMP算法

    在很多地方也都經(jīng)??吹街v解KMP算法的文章,看久了好像也知道是怎么一回事,但總感覺有些地方自己還是沒有完全懂明白。這兩天花了點時間總結(jié)一下,有點小體會,我希望可以通過我自己的語言來把這個算法的一些細(xì)節(jié)梳理清楚,也算是考驗一下自己有真正理解這個算法
    2022-02-02

最新評論

湘潭市| 应城市| 岚皋县| 缙云县| 屏山县| 横山县| 朔州市| 浮山县| 苏尼特左旗| 工布江达县| 大石桥市| 衡山县| 武隆县| 防城港市| 龙江县| 鲜城| 托里县| 娄底市| 新乡县| 洪湖市| 常州市| 辽宁省| 宁晋县| 梅州市| 东兴市| 巴彦淖尔市| 岐山县| 靖江市| 边坝县| 上杭县| 攀枝花市| 荆州市| 吉木萨尔县| 赞皇县| 汝南县| 西宁市| 苏州市| 大新县| 察雅县| 和林格尔县| 灵山县|