Spring自动装配和线程安全

时间:2016-07-17 22:04:19

标签: 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";
    }
}

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

当我们使用@Autowired

时,Spring是否会自动处理此类多线程问题

2 个答案:

答案 0 :(得分:4)

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";
    }
}

如果你对这个终点进行压力测试,你肯定会迟早收到错误信息 - 春天不会做任何事情来防止你自己在脚下射击。

答案 1 :(得分:0)