이번 섹션2의 강의 내용은 [섹션3]부터 시작될 JPA를 사용한 API 최적화를 위한 준비 과정으로써,
미리 DB에 샘플데이터를 추가해놓는 과정이었다.
이 과정에서 우리는 @PostConstruct 어노테이션을 사용하여 샘플데이터를 삽입하는 부분을 초기화 로직으로 실행되도록 하였는데, 이에 대한 자세한 내용을 알아보자.
1. 스프링 빈의 라이프 사이클
스프링 컨테이너 생성 -> 스프링 빈 생성 -> 의존관계 주입 -> 초기화 콜백 -> 사용 -> 소멸전 콜백 -> 스프링 종료
위와 같이 동작사는 스프링 빈의 라이프사이클 상에서 , 스프링은 빈을 사용하기 직전 시점과
다 사용한 후 소멸시키기 이전 시점을 콜백 시킬 수 있도록 지원해준다.
위 두 시점을 pointing 하여 콜백 할 수 있는 어노테이션이 바로 다음 두 어노테이션 이다.
@PostConstruct : 생성된 스플링 빈이 모두 DI 되고난 이후, 사용하기 직전에 콜백
@PreDestroy : 스프링 빈을 다 사용한 후, 스프링을 종료하기 이전에 콜백
따라서 이 두 어노테이션 중 @PostConstruct를 사용하면, 서버가 띄워졌을 때 디폴트로 해야 하는 초기화 작업을 적용시킬 수 있다.
- 주의할 점은 @PostConstruct와 @Transactional을 함께 사용하면, 오류가 날 수 도 있다는 점이다.
따라서 강의에서는 먼저 @Transactional을 사용하여 초기화된 Entity를 삽입하는 부분을 메소드화한 후, 그 메소드를 @PostConstruct 안에서 호출시켰다.
/**
* userA가 JPA1, JPA2책을 사고 / userB가 SPRING1, SPRING2 책을 사도록 초기화 시켜둠
* */
@Component
@RequiredArgsConstructor
public class InitDb {
private final InitService initService;
/** @PostConstruct Spring Bean이 다 DI 되고 나서 마지막에 수행됨 */
@PostConstruct
public void init(){
initService.dbInit1();
initService.dbInit2();
}
@Component
@RequiredArgsConstructor
@Transactional
static class InitService{
private final EntityManager em;
public void dbInit1(){
Member member = createMember("userA", "서울", "1", "1111");
em.persist(member);
Book book1 = createBook("JPA1 BOOK", 10000, 100);
em.persist(book1);
Book book2 = createBook("JPA2 BOOK", 20000, 100);
em.persist(book2);
OrderItem orderItem1 = OrderItem.createOrderItem(book1, 10000, 1);
OrderItem orderItem2 = OrderItem.createOrderItem(book2, 20000, 2);
Order order = Order.createOrder(member, createDelivery(member), orderItem1, orderItem2);
em.persist(order);
}
public void dbInit2(){
Member member = createMember("userB", "진주", "2", "2222");
em.persist(member);
Book book1 = createBook("SPRING1 BOOK", 20000, 200);
em.persist(book1);
Book book2 = createBook("SPRING2 BOOK", 40000, 300);
em.persist(book2);
OrderItem orderItem1 = OrderItem.createOrderItem(book1, 20000, 3);
OrderItem orderItem2 = OrderItem.createOrderItem(book2, 40000, 4);
Order order = Order.createOrder(member, createDelivery(member), orderItem1, orderItem2);
em.persist(order);
}
private Member createMember(String name, String city, String street, String zipcode){
Member member = new Member();
member.setName(name);
member.setAddress(new Address(city, street, zipcode));
return member;
}
private Book createBook(String name, int price, int stockQuantity){
Book book = new Book();
book.setName(name); book.setPrice(price); book.setStockQuantity(stockQuantity);
return book;
}
private Delivery createDelivery(Member member){
Delivery delivery = new Delivery();
delivery.setAddress(member.getAddress());
return delivery;
}
}
}