大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 hot資訊 Spring作用域的快速指南

Spring作用域的快速指南

更新時間:2022-12-05 11:06:49 來源:動力節點 瀏覽1641次

1. 概述

在這個Spring教程中,我們將了解不同類型的bean Spring框架的范圍。

bean的范圍定義bean的生命周期和能見度的情況下我們使用它。

最新版本的Spring框架定義了6種范圍:

單例

原型

請求

會話

應用程序

websocket

最后四范圍所提到的,請求、會話,應用程序和websocket,只有在理解網絡應用程序可用。

2. 單例對象范圍

當我們使用單例范圍定義bean,容器創建bean的一個實例;所有bean名稱的請求將返回相同的對象,這是緩存。任何修改對象將反映在所有bean的引用。這個范圍是默認值如果沒有指定其他范圍。

讓我們創建一個實體來例證了范圍的概念:

public class Person {
    private String name;
    // standard constructor, getters and setters
}

之后,我們定義的bean singleton范圍通過使用@ scope注釋:

@Bean
@Scope("singleton")
public Person personSingleton() {
    return new Person();
}

我們也可以使用一個常數,而不是字符串值在以下方式:

@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)

現在我們可以繼續編寫一個測試表明,兩個對象指的是相同的bean將有相同的價值觀,即使只有一個人改變他們的國家,他們都是引用同一個bean實例:

private static final String NAME = "John Smith";
@Test
public void givenSingletonScope_whenSetName_thenEqualNames() {
    ApplicationContext applicationContext = 
      new ClassPathXmlApplicationContext("scopes.xml");
    Person personSingletonA = (Person) applicationContext.getBean("personSingleton");
    Person personSingletonB = (Person) applicationContext.getBean("personSingleton");
    personSingletonA.setName(NAME);
    Assert.assertEquals(NAME, personSingletonB.getName());
    ((AbstractApplicationContext) applicationContext).close();
}

作用域。xml文件在這個例子中應該包含的xml定義bean使用:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="personSingleton" class="org.baeldung.scopes.Person" scope="singleton"/>    
</beans>

3.原型范圍

原型的bean將返回一個不同的實例范圍每次請求的容器。它通過設置值定義原型在bean定義:@ scope注釋

@Bean
@Scope("prototype")
public Person personPrototype() {
    return new Person();
}

我們還可以使用一個常數如單例的范圍:

@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)

現在我們將編寫一個類似的測試,顯示了兩個對象請求與原型相同的bean名稱范圍。他們會有不同的國家不再是指相同的bean實例:

private static final String NAME = "John Smith";
private static final String NAME_OTHER = "Anna Jones";
@Test
public void givenPrototypeScope_whenSetNames_thenDifferentNames() {
    ApplicationContext applicationContext = 
      new ClassPathXmlApplicationContext("scopes.xml");
    Person personPrototypeA = (Person) applicationContext.getBean("personPrototype");
    Person personPrototypeB = (Person) applicationContext.getBean("personPrototype");
    personPrototypeA.setName(NAME);
    personPrototypeB.setName(NAME_OTHER);
    Assert.assertEquals(NAME, personPrototypeA.getName());
    Assert.assertEquals(NAME_OTHER, personPrototypeB.getName());
    ((AbstractApplicationContext) applicationContext).close();
}

作用域。xml文件類似于前一節中給出的一個而添加xml定義的bean原型范圍:

<bean id="personPrototype" class="org.baeldung.scopes.Person" scope="prototype"/>

4. 認識到網絡范圍

正如前面提到的,有四個額外的范圍,只有在理解網絡應用程序上下文。我們在實踐中很少使用這些。

請求范圍為一個HTTP請求,創建一個bean實例在會話范圍創建一個HTTP會話bean實例。

應用范圍創建bean實例的生命周期ServletContext,和websocket創建為一個特定的websocket會話范圍。

讓我們創建一個類實例化bean的使用:

public class HelloMessageGenerator {
    private String message;    
    // standard getter and setter
}

(1)請求范圍

我們可以定義bean的請求范圍使用@ scope注釋:

@Bean
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public HelloMessageGenerator requestScopedBean() {
    return new HelloMessageGenerator();
}

proxyMode屬性是必要的,因為目前的web應用程序上下文的實例化,沒有主動請求。Spring創建一個代理作為依賴項注入,并實例化目標bean需要時在一個請求。

我們也可以使用一個@RequestScope由注釋,充當一個上述定義的快捷方式:

@Bean
@RequestScope
public HelloMessageGenerator requestScopedBean() {
    return new HelloMessageGenerator();
}

接下來,我們可以定義一個控制器requestScopedBean注入引用。我們需要訪問相同的請求兩次來測試web具體范圍。

如果我們顯示消息每次請求運行時,我們可以看到,該值重置為零,即使后來改變的方法。這是因為不同的bean實例為每個請求返回。

@Controller
public class ScopesController {
    @Resource(name = "requestScopedBean")
    HelloMessageGenerator requestScopedBean;
    @RequestMapping("/scopes/request")
    public String getRequestScopeMessage(final Model model) {
        model.addAttribute("previousMessage", requestScopedBean.getMessage());
        requestScopedBean.setMessage("Good morning!");
        model.addAttribute("currentMessage", requestScopedBean.getMessage());
        return "scopesExample";
    }
}

(2)會話范圍

我們可以定義的bean會話范圍以類似的方式:

@Bean
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public HelloMessageGenerator sessionScopedBean() {
    return new HelloMessageGenerator();
}

還有一個專門的由注釋我們可以用來簡化bean定義:

@Bean
@SessionScope
public HelloMessageGenerator sessionScopedBean() {
    return new HelloMessageGenerator();
}

接下來,我們定義了一個控制器與sessionScopedBean參考。再一次,我們需要運行兩個請求為了顯示消息字段的值是相同的會話。

在這種情況下,當請求是由第一次消息為空值。然而,一旦改變,這個值保留為后續請求返回相同的bean的實例對整個會話。

@Controller
public class ScopesController {
    @Resource(name = "sessionScopedBean")
    HelloMessageGenerator sessionScopedBean;
    @RequestMapping("/scopes/session")
    public String getSessionScopeMessage(final Model model) {
        model.addAttribute("previousMessage", sessionScopedBean.getMessage());
        sessionScopedBean.setMessage("Good afternoon!");
        model.addAttribute("currentMessage", sessionScopedBean.getMessage());
        return "scopesExample";
    }
}

(3)應用范圍

應用范圍創建bean實例的生命周期ServletContext。

這是類似于單例的范圍,但是有一個非常重要的區別對于bean的范圍。

當bean是應用程序作用域,同樣的bean的實例共享多個基于servlet的應用程序運行在同一ServletContext,而單范圍內bean只局限于單個應用程序上下文。

讓我們創建bean與應用范圍:

@Bean
@Scope(
  value = WebApplicationContext.SCOPE_APPLICATION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public HelloMessageGenerator applicationScopedBean() {
    return new HelloMessageGenerator();
}

類似于請求和會話作用域,我們可以使用更短的版本:

@Bean
@ApplicationScope
public HelloMessageGenerator applicationScopedBean() {
    return new HelloMessageGenerator();
}

現在讓我們創建一個控制器,這個bean引用:

@Controller
public class ScopesController {
    @Resource(name = "applicationScopedBean")
    HelloMessageGenerator applicationScopedBean;
    @RequestMapping("/scopes/application")
    public String getApplicationScopeMessage(final Model model) {
        model.addAttribute("previousMessage", applicationScopedBean.getMessage());
        applicationScopedBean.setMessage("Good afternoon!");
        model.addAttribute("currentMessage", applicationScopedBean.getMessage());
        return "scopesExample";
    }
}

applicationScopedBean在這種情況下,一旦設置,該值為所有后續請求消息將被保留,會話,甚至不同的servlet將訪問這個bean的應用程序,它運行在相同的ServletContext。

(4)WebSocket范圍

最后,讓我們創建的bean websocket范圍:

@Bean
@Scope(scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS)
public HelloMessageGenerator websocketScopedBean() {
    return new HelloMessageGenerator();
}

當第一次訪問,WebSocket范圍bean存儲在WebSocket會話屬性。然后返回相同的bean實例時,在整個WebSocket會話bean訪問。

我們也可以說,它表現出單的行為,但只局限于一個WebSocket會話。

以上就是關于“Spring作用域的快速指南”的介紹,大家如果想了解更多相關知識,不妨來關注一下本站的Java在線學習技術文檔,里面的課程內容細致全面,很適合沒有基礎的小伙伴學習,希望對大家能夠有所幫助哦。

提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 波多野结衣免费一区二区三区香蕉 | 久久亚洲国产的中文 | 亚洲日本在线观看 | 欧美三区在线 | 国产精品国产三级国产普通话 | 国产成人丝袜网站在线观看 | 欧美日韩国产精品 | 激情影院在线 | 一级毛片美国一级j毛片不卡 | 国内精品久久久久影院嫩草 | 亚洲成人av | 亚洲女人毛片 | 色综合欧美 | 欧美白人猛性xxxxx交69 | 婷婷网五月天天综合天天爱 | 国产一级做a爱片久久毛片a | 精品哟哟国产在线观看 | 九九在线精品 | 亚洲高清视频网站 | 欧美成人精品一区二三区在线观看 | 99精品久久 | 国产精品成人网 | 精品一区二区三区在线观看 | 午夜一级毛片看看 | 奇米线在人线免费视频 | 亚洲免费资源 | 毛片视频网站在线观看 | 九色国产 | 99自拍视频在线观看 | 亚洲大片在线观看 | 性夜黄a爽爽免费视频国产 性夜影院爽黄a爽免费看网站 | 久久精品免费看 | 激情五月婷婷综合网 | 欧美精品成人 | 日韩在线视频一区二区三区 | 欧美精品亚洲精品日韩专区 | 国产在线精品观看 | 日韩亚洲成a人片在线观看 日韩亚洲第一页 | 亚洲高清免费视频 | 99色这里只有精品 | 一级黄网|