Spring 멤버필드 주의할 점 - 201211211yj/Spring-Boot-Start GitHub Wiki
//Bad Case
@Component
public class UserService {
private User user;
@Autowired
private UserDao dao;
public int update(int id, String name) {
this.user.setId(id);
this.user.setName(name);
return userDao.updateUser(user);
}
}
//Good case
@Component
public class UserService {
@Autowired
private UserDao dao;
public int update(int id, String name) {
User user = new User();
user.setId(id);
user.setName(name);
return userDao.updateUser(user);
}
}
Spring Bean은 기본적으로 singleton 동작이기 때문에 멀티스레드 환경을 고려한 Stateless 서비스 Bean에서 필드(멤버변수)로 상태 데이터를 저장하는 용도로 사용하면 안됩니다. User 객체는 요청되는 Thread 별로 달리 세팅되므로 Bean의 멤버변수로 선언하지 말고 new로 생성해야 합니다.
Bean으로 등록된 UserService는 Singleton으로 떠있음(모든 스레드마다 공유) 따라서 멤버필드로 지정하면 User도 모든 스레드마다 공유됨
그래서 1을 업데이트 치려다가 2가 중간에 껴서 업데이트 될 수 있음 고로 쓰레드별로 new User()를 해서 각 Thread별로 다른 User를 사용한다.