转载

再谈Spring(一):Bean的作用域

今天准备开始一个Spring系列文章,主要记录一些学习和使用Spring过程中遇到的小知识,所以我起了《 再谈Spring 》的名字。

正文

Spring是一个轻量级的IOC和AOP容器框架。是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。

Spring属于低侵入式设计,代码的污染极低。并且Spring的控制反转机制将对象之间的依赖关系交由框架处理,减低组件的耦合性。通过IOC容易来创建一个个的Bean,并且注入到你需要的地方。

今天我们来一起 看看Spring Bean的作用域 吧,我们使用简单易上手的SpringBoot来进行介绍。

SpringBoot 是 Spring 开源组织下的子项目,是 Spring 组件一站式解决方案,主要是简化了使用 Spring 的难度,简省了繁重的配置,提供了各种启动器,开发者能快速上手。

接下来,我们一起搭建一个SpringBoot项目吧~

项目目录如下所示:

再谈Spring(一):Bean的作用域

启动类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:

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方法来启动项目:

再谈Spring(一):Bean的作用域

然后打开浏览器,效果如下:

再谈Spring(一):Bean的作用域

好了,这里我们简单搭建了一个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);
    }

}

复制代码

输出结果如下:

再谈Spring(一):Bean的作用域

由图中,可以看到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 {

    // 下边可以定义任意的业务处理逻辑
    // ....
}

复制代码

输出结果如下:

再谈Spring(一):Bean的作用域

由图中可以看出,当前两次注入的对象实例不是同一个,也就是说在当前IOC容器中存在多个TestService的对象实例。

当我们使用@Scope("singleton")进行标注Bean时,会发现结果变为了true,验证了默认的作用域确实是singleton。

接下来,我会持续更新在使用Spring过程中使用到的一些小知识点,希望大家可以持续关注~

如果对你有帮助,记得点赞哈,欢迎大家关注我的博客,关注公众号(文强的技术小屋),学习更多技术知识,一起遨游知识海洋~ 再谈Spring(一):Bean的作用域

原文  https://juejin.im/post/5dfce5b46fb9a016493953bd
正文到此结束
Loading...