草庐IT

java - 我应该把我的 ThreadLocals 放在一个 Spring 注入(inject)的单例中吗?

coder 2023-05-11 原文

一些人(例如在服务器端 http://www.theserverside.com/news/thread.tss?thread_id=41473 )建议使用 ThreadLocal 对象与使用全局变量一样糟糕。 我想如果您将它们设为公共(public)静态变量,这是正确的。 那么问题是很难判断它在哪里使用,在哪里改变等等。

在我的 spring DI tomcat web-app 中,如果我让 spring 创建一个包含我的 ThreadLocal(s) 的单例对象,然后将该单例注入(inject)任何需要它的类,它似乎可以解决这个问题。

所以我的单例看起来像这样:

@Component
public class Username {
    private ThreadLocal<String> username;

    public Username() {
        username = new ThreadLocal<String>();
    }

    public String getUsername()
        return username.get();
    }

    public void setUsername(String name) {
        username.set(name);
    }
}

可能需要它的类如下所示:

@Service
public class addEntryTransaction {

    @Autowired
    Username username;

    public void method() {
        ...
        log("Method called by "+username.getUsername());
        ...
     }

}

这仍然具有不必通过许多无关的层传递用户名的好处,因此保持方法参数更简单。 @Autowired 是该类使用该变量的声明。

这种方法的优缺点是什么?

最佳答案

正如@axtavt 提到的,request-scoped beans当您谈论 Web 应用程序时,它通常是 ThreadLocals 更简洁、更优雅的替代品。事实上,在幕后,Spring 使用它自己的 ThreadLocal 变量实现了请求范围的 bean(参见 RequestContextHolder)。 ThreadLocal 和作用域 bean 都为您提供了相同的基本优势 - 无需通过调用堆栈手动传递对象即可访问对象。

但是,有一种情况是 ThreadLocal 变量胜过作用域 bean,这是在您想从 Spring 的 bean 生命周期之外访问对象的情况下。 JSP taglib 中就是一个很好的例子。 Taglib 实例由 servlet 容器而不是 Spring 控制,因此不能参与 Spring 的 IoC 框架,因此不能与请求范围的 bean(或任何其他 bean,就此而言)连接。但是,它们可以访问 ThreadLocal 变量。有一些方法可以解决这个问题,但有时 ThreadLocals 是最简单的方法。

ThreadLocal 的功能缺点之一是它们在数据从线程传递到线程的应用程序中不是很有用(InheritableThreadLocal 有时会有所帮助,但并非总是如此)。在这种情况下,Spring 的作用域 bean 也会失败,因为它们是使用 ThreadLocal 实现的。

因此,如果您有一个 Spring Web 应用程序,并且希望访问特定于当前请求线程的对象的 Spring bean,那么我建议您使用请求范围的 bean。如果您需要访问那些超出 Spring bean 控制范围的对象,那么 ThreadLocal 可能会更容易,尽管我会尽量使事情与作用域 bean 一起工作。

关于java - 我应该把我的 ThreadLocals 放在一个 Spring 注入(inject)的单例中吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2218282/

有关java - 我应该把我的 ThreadLocals 放在一个 Spring 注入(inject)的单例中吗?的更多相关文章

  1. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  2. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  3. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  4. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  5. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  6. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  7. ruby - 为什么 SecureRandom.uuid 创建一个唯一的字符串? - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?

  8. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  9. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  10. ruby-on-rails - Rails - 从另一个模型中创建一个模型的实例 - 2

    我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案

随机推荐