Spring Singleton 范围与应用程序范围

2023-12-29

单例和应用程序弹簧范围有什么区别?

我知道单例作用域为每个应用程序创建一个实例,并且应用程序作用域以相同的方式工作,那么主要区别是什么?

我需要一个例子来展示其中的区别。


要了解应用程序范围和单例范围之间的区别,您需要了解 ServletContext 和 ApplicationContext 是什么。

A ServletContext在同一 servlet 容器(例如 Tomcat)上的所有 servlet 之间共享。这是一个 Java EE 类(它属于包javax.servlet)。 Bean 注释为@ApplicationScope绑定到 ServletContext。

An ApplicationContext代表一个 Spring IoC 容器,因此它是一个 Spring 特定的类(它属于包org.springframework.context)。单例作用域 bean 绑定到 ApplicationContext。

您可以在同一个 servlet 容器中拥有多个 IoC 容器,因此您可以拥有多个相同类型的单例 bean,但每种类型只能有一个应用程序范围的 bean。

我提供了一个使用 Spring Boot 和 Spring MVC 的示例。

我们还需要介绍一下DispatcherServlet。 DispatcherServlet 接收 HTTP 请求并将它们转发到适当的控制器。 ApplicationContext 与每个 DispatcherServlet 相关联。可以将 Spring 配置为创建多个 DispatcherServlet 并将不同的 ApplicationContext 关联到每个 DispatcherServlet。

请注意,在标准配置中只有一个 DispatcherServlet,因此通常无法区分单例作用域 bean 和应用程序作用域 bean。我还想指出,除了提供这两个范围之间差异的具体示例之外,我认为我将向您展示的自定义配置没有实际用途。

下图显示了示例中所有元素之间的关系:

让我们看一下代码。请注意包名!

包装内com.example.demo.beans我们创建了 2 个 bean。 beans初始化时会生成一个随机数,以便我们区分它们。

@ApplicationScope
@Component
public class MyApplicationScopeBean {

    private final double id = Math.random();

    public double getId() {
        return id;
    }
}
// Singleton is the default scope
@Component
public class MySingletonBean {

    private final double id = Math.random();

    public double getId() {
        return id;
    }
}

启动类放入com.example.demo:

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        // The first ApplicationContext is instantiated here
        // (it is also returned by the method).
        SpringApplication.run(DemoApplication.class, args);
    }

    /**
     * A new DispatcherServlet is instantiated and registered.
     */
    @Bean
    public ServletRegistrationBean mvc2() {

        // A new ApplicationContext is created, using a dedicated Configuration class.
        AnnotationConfigWebApplicationContext secondApplicationContext = new AnnotationConfigWebApplicationContext();
        secondApplicationContext.register(Mvc2Config.class);

        DispatcherServlet dispatcherServlet = new DispatcherServlet();
        dispatcherServlet.setApplicationContext(secondApplicationContext);

        DispatcherServletRegistrationBean servletRegistrationBean = new DispatcherServletRegistrationBean(dispatcherServlet, "/second/*");
        servletRegistrationBean.setName("second");

        return servletRegistrationBean;
    }
}

在同一个包中,我们还放置了将绑定到 Spring Boot 生成的默认 DispatcherServlet 的控制器:

@RestController
public class FirstController {

    @Autowired
    private MyApplicationScopeBean applicationScopeBean;

    @Autowired
    private MySingletonBean singletonBean;

    @GetMapping("/first/demo")
    public String output() {
        return "applicationScope=" + applicationScopeBean.getId() + ", singleton=" + singletonBean.getId();
    }
}

包装内com.example.demo.mvc2我们放置第二个配置类:

@Configuration
@ComponentScan(basePackages = {"com.example.demo.mvc2", "com.example.demo.beans"})
@EnableWebMvc
public class Mvc2Config {
}

控制器绑定到第二个 DispatcherServlet:

@RestController
public class SecondController {

    @Autowired
    private MyApplicationScopeBean applicationScopeBean;

    @Autowired
    private MySingletonBean singletonBean;

    @GetMapping("/demo")
    public String output() {
        return "applicationScope=" + applicationScopeBean.getId() + ", singleton=" + singletonBean.getId();
    }
}

如果运行代码,您可以看到应用程序作用域 bean 的 id 在两个控制器中相同,而单例 bean 的 id 发生了变化:

http://localhost:8080/first/demo

applicationScope=0.8685117272969953,单例=0.23475401462261436

http://localhost:8080/second/demo

applicationScope=0.8685117272969953,单例=0.8390865330171554

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Singleton 范围与应用程序范围 的相关文章

随机推荐

  • 如何在程序结束时关闭数据库连接?

    在Java程序中 我有一个单例类来保存数据库连接 该连接由整个程序使用 如何告诉Java在程序结束时关闭连接 我可以在 main 末尾放置一个 connection close 语句 但是如果程序意外结束 例如 由于程序中某处未捕获的异常或
  • PHP 在编辑模式下显示下拉列表中选定的值

    这个问题已经被问过 但我的问题很简单 在我的帐户页面中 我在下拉列表中显示了员工所在国家 地区 在编辑模式下如何选择组合中的值 假设您的用户所在国家 地区是 user country以及所有国家 地区的列表 all countries ar
  • 如何从c#返回List并通过com在vc++中使用它

    如何从 C 方法返回 List 以及在 C 中使用 List 返回值 您可以指导如何操作吗 我将按照我的完整方案进行操作 在 c DemoLib cs 中 usng System using System Collections Gener
  • 使用 ffmpeg 命令在视频中添加多个元数据

    添加单个元数据的命令工作正常 ffmpeg i var www html public uploads wp video akka mov metadata kKeyContentIdentifier com apple quicktime
  • 在 numpy 一维数组中查找拐点和驻点

    假设我有以下 numpy 数组 import numpy as np import matplotlib pyplot as plt x np array 11 53333333 11 86666667 11 1 10 66666667 1
  • 无法更改 unicode 字符的字体颜色

    确实很小的事情 但我在 Joomla 前端编辑页面的发布按钮上有这些日历图标 我为此使用 Unicode 字符 U 1F5D2 但我似乎无法使用 CSS 更改其颜色 我试图将其变成白色 浏览器检查员说它是白色的 但显然不是 请参阅此处的示例
  • 在 ARMv8-A Linux 上禁用 CPU 缓存 (L1/L2)

    我想在运行 Linux 的 ARMv8 A 平台上禁用低级缓存 以便独立于缓存访问来测量优化代码的性能 对于英特尔系统 我找到了以下资源 有没有办法在 Linux 系统上禁用 CPU 缓存 L1 L2 https stackoverflow
  • TensorFlow - Saver.restore 未恢复所有参数

    我训练了双向 LSTM 类型的 RNN 近 24 小时 由于误差波动 我决定在允许其继续训练之前减少学习量 由于模型在每个时期都使用 Saver save sess file 保存 因此我终止了训练 CTC 损失已最小化至大约 115 现在
  • 使用 gruntjs 组合并缩小所有 Bower 库

    有没有办法自动将所有 Bower 安装的库合并并缩小为 1 个文件 首先我尝试了最基本的方法 将所有 js所有子目录中的文件 uglify options compress true my target files vendor js bo
  • 如何禁用 libsvm (java) 中的控制台输出

    我正在使用 libsvmjava并且遇到了与描述类似的问题here https stackoverflow com questions 8302519 suppressing the output in libsvm python对于蟒蛇
  • 如何捕获java.sql.SQLIntegrityConstraintViolationException?

    我的应用程序使用 JPA JavaDB 当我尝试保留违反约束的对象时 我得到SQLIntegrityConstraintViolationException http docs oracle com javase 7 docs api ja
  • 为什么 Mongoose 不验证更新?

    我有这个代码 var ClientSchema new Schema name type String required true trim true var Client mongoose model Client ClientSchem
  • 导航控制器栏被切断

    如果通过选择隐藏状态栏status bar style hide during application launch我正在自定义导航栏 如下所示 UINavigationBar appearance setBackgroundImage U
  • 以日历日为单位分割间隔的持续时间

    我有以下数据集 显示一集的开始和结束 日期和时间 ep lt data frame start c 2009 07 13 23 45 00 2009 08 14 08 30 00 2009 09 16 15 30 00 end c 2009
  • “POSIX”是什么意思?

    什么是 POSIX 我已阅读维基百科文章 http en wikipedia org wiki POSIX每次遇到这个词我都会读它 事实是我从来没有真正理解它是什么 任何人都可以通过解释 POSIX 的需要 来向我解释一下吗 POSIX h
  • 尝试混合属于不同事务的对象

    pony orm core TransactionError An attempt to mix objects belonging to different transactions 我知道这个错误是描述性的 我只是不明白为什么会发生 我
  • HikariCP 连接过多

    我有一个Java Servlet 我想将连接池与jdbc 数据库 mysql 一起使用 所以这就是我正在做的 这个类是公共最终类DBConnector private static final HikariDataSource dataSo
  • 如何仅为一个 Razor 页面设置 `ValidationVisitor.MaxValidationDepth` = 1?

    我该如何改变ValidationVisitor MaxValidationDepth在本地为一个 Razor 页面阻止验证子对象 我不想在全球范围内改变它MvcOptions MaxValidationDepth就像文档中描述的那样 最大递
  • 如何在默认 Spring Data JPA 方法上添加 QueryHints?

    我可以将查询缓存与 Spring Data JPA 一起用于我的自定义查询方法 如下所示 public interface CountryRepository extends JpaRepository
  • Spring Singleton 范围与应用程序范围

    单例和应用程序弹簧范围有什么区别 我知道单例作用域为每个应用程序创建一个实例 并且应用程序作用域以相同的方式工作 那么主要区别是什么 我需要一个例子来展示其中的区别 要了解应用程序范围和单例范围之间的区别 您需要了解 ServletCont