再談Spring(一):Bean的做用域

(尊重勞動成果,轉載請註明出處:juejin.im/post/5dfce5…
java

前言

今天準備開始一個Spring系列文章,主要記錄一些學習和使用Spring過程當中遇到的小知識,因此我起了《再談Spring》的名字。web


正文

Spring是一個輕量級的IOC和AOP容器框架。是爲Java應用程序提供基礎性服務的一套框架,目的是用於簡化企業應用程序的開發,它使得開發者只須要關心業務需求。spring

Spring屬於低侵入式設計,代碼的污染極低。而且Spring的控制反起色制將對象之間的依賴關係交由框架處理,減低組件的耦合性。經過IOC容易來建立一個個的Bean,而且注入到你須要的地方。apache

今天咱們來一塊兒看看Spring Bean的做用域吧,咱們使用簡單易上手的SpringBoot來進行介紹。瀏覽器

SpringBoot 是 Spring 開源組織下的子項目,是 Spring 組件一站式解決方案,主要是簡化了使用 Spring 的難度,簡省了繁重的配置,提供了各類啓動器,開發者能快速上手。bash

接下來,咱們一塊兒搭建一個SpringBoot項目吧~session

項目目錄以下所示: app

在這裏插入圖片描述
啓動類StartApplication以下:

package com.ywq;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/** * created by yangwenqiang on 2019-11-30 */

@SpringBootApplication
public class StartApplication {
    // SpringBoot服務的啓動入口
    public static void main(String[] args) {
        SpringApplication.run(StartApplication.class,args);
    }
}
複製代碼

TestController:框架

package com.ywq.controller;

import com.ywq.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/** * created by yangwenqiang on 2019-11-30 */
@RequestMapping("/test")
@RestController
public class TestController {

    @RequestMapping(value = "/scopeTest", method = RequestMethod.GET)
    public String testScope(){

        return "This is Scope Test!";
    }
}

複製代碼

TestService:maven

package com.ywq.service;

import org.springframework.stereotype.Service;

/** * created by yangwenqiang on 2019-11-30 */

@Service
public class TestService {

    // 下邊能夠定義任意的業務處理邏輯
    // ....
}

複製代碼

配置文件application.properties:

server.port=8632
複製代碼

Maven配置文件pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!--指定parent的starter, 能夠省去不少配置-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
    </parent>

    <groupId>com.ywq</groupId>
    <artifactId>bean-scope</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--導入SpringBoot web starter-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <!--添加SpringBoot的編譯插件-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
複製代碼

接下來,咱們能夠直接運行main方法來啓動項目:

在這裏插入圖片描述
而後打開瀏覽器,效果以下:
在這裏插入圖片描述

好了,這裏咱們簡單搭建了一個SpringBoot項目,接下來,咱們來對Spring中Bean的做用域作一個簡單的介紹吧~

Spring框架支持如下五種Bean的做用域:

  • singleton : bean在每一個Spring IOC 容器中只有一個實例
  • prototype:一個bean的定義能夠有多個實例。
  • request:每次http請求都會建立一個bean,該做用域僅在基於web的Spring ApplicationContext情形下有效。
  • session:在一個HTTP Session中,一個bean定義對應一個實例。該做用域僅在基於web的Spring ApplicationContext情形下有效。
  • global-session:在一個全局的HTTP Session中,一個bean定義對應一個實例。該做用域僅在基於web的Spring ApplicationContext情形下有效。缺省的Spring bean 的做用域是Singleton

其中,singleton是Spring默認的Bean做用域,也就是說在當前的IOC容器中只存在一個當前對象。

接下來,咱們作一個簡單的驗證:

修改TestController:

package com.ywq.controller;

import com.ywq.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/** * created by yangwenqiang on 2019-11-30 */
@RequestMapping("/test")
@RestController
public class TestController {

    @Autowired
    private TestService testService;

    @Autowired
    private TestService testService2;

    @RequestMapping(value = "/scopeTest", method = RequestMethod.GET)
    public String testScope() {
        // 這裏判斷咱們注入的TestService的兩個實例對象是不是同一個
        return String.valueOf(testService == testService2);
    }

}

複製代碼

輸出結果以下:

在這裏插入圖片描述
由圖中,能夠看到IOC容器給咱們注入了兩個TestService的對象實例,可是實際上是同一個對象,由於默認使用了單例。

當咱們指定當前要使用多例的時候,能夠在定義Bean的時候進行標註,以下所示:

package com.ywq.service;

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

/** * created by yangwenqiang on 2019-11-30 */

@Service
@Scope("prototype")
public class TestService {

    // 下邊能夠定義任意的業務處理邏輯
    // ....
}

複製代碼

輸出結果以下:

在這裏插入圖片描述
由圖中能夠看出,當前兩次注入的對象實例不是同一個,也就是說在當前IOC容器中存在多個TestService的對象實例。

當咱們使用@Scope("singleton")進行標註Bean時,會發現結果變爲了true,驗證了默認的做用域確實是singleton。

接下來,我會持續更新在使用Spring過程當中使用到的一些小知識點,但願你們能夠持續關注~


若是對你有幫助,記得點贊哈,歡迎你們關注個人博客,關注公衆號(文強的技術小屋),學習更多技術知識,一塊兒遨遊知識海洋~

相關文章
相關標籤/搜索