弹簧自动装配和螺纹安全

Nic*_*k M 6 spring thread-safety autowired

我是Spring的新手,最近创建了一个测试RESTful Web服务应用程序.我遵循Spring @Autowiring注入bean的方式.以下是我的代码和问题:

@Service
public class HelloWorld {       

    @Autowired
    private HelloWorldDaoImpl helloWorldDao;

    public void serviceRequest() {
        helloWorldDao.testDbConnection();
    }

}

@RestController
public class HelloWorldController {

    @Autowired
    private HelloWorld helloWorld;

    @RequestMapping(value = "/test", method = RequestMethod.POST)
    public String test() {
        helloWorld.serviceRequest();
        return "Success";
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我的问题是,当我有两个请求完全同时进入并且它们都共享相同的Service类变量"helloWorld"时,那么我们如何确保为Request 1返回的值不会转到Request 2和反之亦然?

Spring使用时会自动处理这种多线程问题@Autowired吗?

kry*_*ger 5

Spring 本质上不会照顾应用程序的线程安全,特别是因为这发生在完全不同的层上。自动装配(和Spring代理)与它无关,它只是一种将相关组件组装成一个整体的机制。

您的示例也不是非常具有代表性的示例,因为您展示的两个bean实际上都是不可变的。没有共享状态可以被并发请求潜在地重用。为了说明Spring确实不关心您的线程安全,您可以尝试以下代码:

@Service
public class FooService {       
    // note: foo is a shared instance variable
    private int foo;

    public int getFoo() {
        return foo;
    }

    public void setFoo(int foo) {
        this.foo = foo;
    }
}

@RestController
public class FooController {

    @Autowired
    private FooService fooService;

    @RequestMapping(value = "/test")
    public String test() {
        int randomNumber = makeSomeRandomNumber();
        fooService.setFoo(randomNumber);
        int retrievedNumber = fooService.getFoo();
        if (randomNumber != retrievedNumber) {
            return "Error! Foo that was retrieved was not the same as the one that was set";
        }

        return "OK";
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您对该端点进行压力测试,则可以保证迟早会收到错误消息-Spring不会采取任何措施来阻止您用脚射击。


Dio*_*ans 0