Repostiroy 계층의 코드를 작성하다가 갑자기 궁금한 점이 생겼다.
이렇게 되면 매 스레드마다 새로운 JdbcTemplate 객체가 생성이 될 것이다.
Config로 아예 DataSource가 주입된 JdbcTemplate을 스프링 빈으로 등록해놓고, 공유해서 사용하면 되지 않을까? 생각했다.
그러면 그냥 @RequiredArgsConstructor
만으로도 쉽게 Repository 레이어를 작성할 수 있을 것이라고 생각했다.
기존에는 다음과 같이 작성한다.
private JdbcTemplate template;
constructor(DataSource dataSource) {
template = new JdbcTemplate(dataSource);
}
즉 주입받은 것(DataSource)을 필드에 그대로 넣지 않고, 주입 받은 것을 활용해서 뭔가 다른 것(JdbcTemplate)을 생성할 필요를 느끼지 못했었따.
이미 DataSource객체가 주입된 JdbcTemplate을 주입받으면 되기 때문이다.
@Repository
@RequiredArgsConstructor
public Repository {
private final JdbcTemplate jdbcTemplate; //이미 DataSource가 주입됨
}
그 이유에 대해 알아보자.
https://stackoverflow.com/questions/17400129/singleton-vs-prototype-jdbctemplate
둘다 괜찮다고 한다. ㅎㅎ...
이와 관련한 공식문서도 링크하겠다.
Instances of the
JdbcTemplate
class are thread-safe, once configured. This is important because it means that you can configure a single instance of aJdbcTemplate
and then safely inject this shared reference into multiple DAOs (or repositories). TheJdbcTemplate
is stateful, in that it maintains a reference to aDataSource
, but this state is not conversational state.
JdbcTemplate은 thread-safe 이므로, single 인스턴스로 다루어도 상관 없다고 한다.
또한 conversational state가 뭔지 궁금해서 찾아보았는데,
https://docs.oracle.com/cd/E19798-01/821-1841/gipjg/index.html
A stateless session bean does not maintain a conversational state with the client. When a client invokes the methods of a stateless bean, the bean’s instance variables may contain a state specific to that client but only for the duration of the invocation. When the method is finished, the client-specific state should not be retained. Clients may, however, change the state of instance variables in pooled stateless beans, and this state is held over to the next invocation of the pooled stateless bean. Except during method invocation, all instances of a stateless bean are equivalent, allowing the EJB container to assign an instance to any client. That is, the state of a stateless session bean should apply across all clients.
Because they can support multiple clients, stateless session beans can offer better scalability for applications that require large numbers of clients. Typically, an application requires fewer stateless session beans than stateful session beans to support the same number of clients.
A stateless session bean can implement a web service, but a stateful session bean cannot.
conversational state란 stateless session으로써 위와 같은 내용을 가지고있다.
이를 통해, 그냥 JdbcTemplate을 주입받아서 사용하도 되겠다! 라고 생각했다.
하지만 Best Practice는 DataSource를 주입받는 것이니, 이 방법을 사용하자.
추가정보 )그리고 build.gradle에
spring-boot-starter-jdbc 를 추가하면 JdbcTemplate을 DataSource와 함께 스프링 빈으로 등록해서 Config 설정을 안해도 싱글톤 빈으로 주입받아서 사용이 가능하다.