Spring对象是否安全?

Sat*_*esh 39 spring

Spring对象是否安全?如果没有,如何使它们的线程安全?

tol*_*ius 107

这是两个不相关的问题:

Spring Beans是否安全?

没有.

Spring有不同的bean 作用域(例如Prototype,Singleton等),但所有这些作用域都是创建bean 强制执行的.例如,每次"注入"此bean时,都会创建一个"prototype"范围的bean,而"singleton"范围的bean将在应用程序上下文中创建一次并共享.还有其他范围,但它们只是定义了何时创建新实例的时间跨度(例如"范围").

如果有多个线程可以访问bean(无论范围是什么),那么上面几乎没有什么与线程安全有关,它只取决于该bean 的设计是否为"线程安全" .

我说"很少,如果有的话"的原因是因为它可能取决于你试图解决的问题.例如,如果您担心2个或更多HTTP请求是否可能为同一个bean创建问题,则会有一个"请求"范围将为每个HTTP请求创建一个新的bean实例,因此您可以"思考"特定bean在多个HTTP请求的上下文中是"安全的".但是Spring仍然不是真正的线程安全,因为如果有几个线程在同一个 HTTP请求中使用这个bean ,它会回到bean设计(的bean支持类的设计).

如何制作/设计一个线程安全的"对象"?

有几种方法,可能在这里列出的时间太长了,但这里有一些例子:

  • 设计你的bean 不可变:例如没有setter,只使用构造函数参数来创建bean.还有其他方法,如Builder模式等.

  • 设计您豆类无状态:比如一个bean是什么可以只是一个函数(或几个).这个bean在大多数情况下可以和应该是无状态的,这意味着它没有任何状态下,只有与您提供的每个时间(在每次调用)函数参数的东西

  • 设计你的bean persistent:这是一个"不可变"的特例,但有一些非常好的属性.通常用于函数式编程,其中Spring(至少尚未)在命令式世界中没有用,但我已经将它们与Scala/Spring项目一起使用.

  • 使用锁设计你的bean [最后的手段]:除非你正在使用更低级别的库,否则我建议不要这样做.原因是我们(人类)在锁定方面并不好.就是我们养育和培养的方式.一切都是平行发生的,我们不需要"暂停下雨,让我得到一把雨伞".然而,当你在谈论"多个事物同时"时,计算机都是关于锁的,因此我们中的一些人(特殊人)正在做他们的公平分享并基于这些锁实现库.大多数其他人只能使用这些库而不用担心并发性.

  • 就"面试问题"而言,你可以提一下,你可以创建自己的[自定义范围](http://static.springsource.org/spring/docs/current/spring-framework-reference/htmlsingle/#beans将被线程约束的-factory-scopes-custom-using(例如[SimpleThreadScope](http://static.springsource.org/spring/docs/current/javadoc-api/org/springframework/context/support/SimpleThreadScope的.html)).但是我觉得上面的内容应该让面试官满意. (5认同)

art*_*est 11

Spring 不保证线程安全。但它提供了有关此事的指导方针。如果您的 bean 有状态,请不要使用单例 bean 范围。

我创建了一个演示来展示具有 Singleton 和 Prototype 范围的 spring bean 的可变性

我专注于有状态的 bean,然后使用 Singleton 和 Prototype 作用域来展示 bean 如何改变它们的状态。

Job 类由 JobPrototype 和 JobSingleton bean 扩展,它们基于活动配置文件集加载。tp 设置配置文件,将属性 spring.profiles.active 设置为 proto(对于原型范围)或单例(对于单例范围)

活动作业豆Autowired里面已经预定方法到的发生变异状态亚军和Runner1豆类Autowired豆定期

public class Job {

    protected int count = 0;

    void counter() {
        this.count++;
    }

    public int getCount() {
        return count;
    }
}



@Component
@Profile("proto")
@Scope("prototype")
public class JobPrototype extends Job {
}

@Component
@Profile("singleton")
public class JobSingleton extends Job {

}

@Component
public class Runner {

    private Logger Log = LoggerFactory.getLogger(this.getClass().getName());
    @Autowired
    private Job job;

    @Scheduled(fixedDelay = 1500)
    void count() {
        this.job.counter();
        Log.info("### Runner: count: " + this.job.getCount());
    }
}

@Component
public class Runner1 {

    private Logger Log = LoggerFactory.getLogger(this.getClass().getName());
    @Autowired
    private Job job;

    @Scheduled(fixedDelay = 1000)
    void count() {
        this.job.counter();
        Log.info("### RunnerOne: count: " + this.job.getCount());
    }

}
Run Code Online (Sandbox Code Playgroud)

结果是

  1. 例作用域

  2. 原型 原型范围

此演示beans_mutability 的完整代码