[내일배움캠프 사전캠프] 18회차 TIL(7/16 목) - 스프링 컨테이너

2026. 7. 16. 15:45·심화_AI를 활용한 백엔드 아키텍처 심화 과정

1. Spring Bean(빈)

Bean이란 스프링 컨테이너가 객체를 생성(new)하고 관리하며, 필요한 곳에 자동으로 주입해주는 객체이다.

Bean 등록 방법

1) @Component 방식

내가 직접 만든 클래스를 Bean으로 등록할 때 사용한다.

@Service, @Repository, @Controller 모두 내부적으로 @Component를 포함하고 있다.

 
@Service
public class ProductService {
}
 

스프링이 실행되면 Component Scan을 통해 @Component 계열의 클래스를 찾아 Bean으로 등록한다.


2) @Configuration + @Bean 방식

수정할 수 없는 외부 라이브러리 클래스 등을 Bean으로 등록할 때 사용한다.

 
@Configuration
public class AppConfig {

    @Bean
    public Apple apple() {
        return new Apple();
    }
}
 

두 방식의 차이

구분 @Component @Configuration + @Bean
사용 대상 내가 만든 클래스 외부 라이브러리 클래스
객체 생성 스프링이 생성 개발자가 직접 생성
Bean 이름 클래스명(memberService) 메서드명(apple)

 


2. 생성자 주입

Spring에서는 생성자 주입(Constructor Injection) 을 가장 권장한다.

@RequiredArgsConstructor를 사용하면 final 필드에 대한 생성자를 Lombok이 자동으로 생성해준다.

 
@Service
@RequiredArgsConstructor
public class ProductService {

    private final OrderRepository orderRepository;
    private final UserRepository userRepository;

}
 

장점

  • 불변 객체 생성 가능
  • 의존성 누락 방지
  • 테스트가 쉬움

3. Singleton(싱글톤)

Spring Bean은 기본적으로 Singleton으로 관리된다.

즉, 사용자 1000명이 요청하더라도 객체는 하나만 생성되고 모두가 공유해서 사용한다.

잘못된 예

 
private int price;
 

필드에 상태를 저장하면 여러 사용자가 동시에 접근하면서 값이 변경될 수 있다.

올바른 예

 
@Service
@RequiredArgsConstructor
public class OrderService {

    private final OrderRepository orderRepository;

    public int order(String userName, int price) {

        int orderPrice = price;

        ...

    }
}
 

지역변수를 사용하면 요청마다 별도의 값이 생성되어 안전하다.


4. JPA 실행 구조

JPA가 실제 SQL을 실행하는 과정은 다음과 같다.

Repository
    ↓
Spring Data JPA
    ↓
JPA (표준 명세)
    ↓
Hibernate
    ↓
Database
 
  • Spring Data JPA : Repository 구현체를 자동 생성
  • JPA : 인터페이스(표준)
  • Hibernate : 실제 SQL 생성 및 실행

5. 엔티티 매핑

JPA는 엔티티 클래스를 DB 테이블과 매핑하여 관리한다.

 
@Entity
@Table(name = "products")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

}
 

주요 어노테이션

  • @Entity : JPA 엔티티
  • @Table : 테이블명 지정
  • @NoArgsConstructor(PROTECTED) : JPA 기본 생성자
  • @Id : 기본키(PK)
  • @GeneratedValue : PK 자동 생성(AUTO_INCREMENT)
  • @Column : 컬럼 옵션 지정

6. 영속성 컨텍스트(Persistence Context)

영속성 컨텍스트는 엔티티를 관리하는 공간(1차 캐시) 이다.

엔티티 상태

  • 비영속(New) : 객체만 생성된 상태, DB와 관계 없음
  • 영속(Managed) : 영속성 컨텍스트에서 관리되는 상태
  • 준영속(Detached) : 영속성 컨텍스트에서 분리된 상태
  • 삭제(Removed) : 삭제 예정 상태

Dirty Checking(변경 감지)

@Transactional 안에서 영속 상태의 엔티티를 수정하면 save()를 호출하지 않아도 변경 사항을 감지하여 트랜잭션 종료 시 자동으로 UPDATE SQL을 실행한다.

 
@Transactional
public void update() {

    Product product = repository.findById(id).get();

    product.changeName("사과");

}
 

→ save() 없이도 UPDATE가 수행된다.


7. 연관관계와 N+1 문제

회원과 주문처럼 엔티티는 서로 연관관계를 가진다.

 
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;
 

여기서 LAZY를 사용하면 실제 필요한 시점에 데이터를 조회한다.

N+1 문제

주문 목록 조회
↓
SELECT * FROM orders      (1번)

↓

for (Order order : orders) {
    order.getMember().getName();
}

↓

회원 조회 쿼리 N번 발생
 

총 1 + N번의 SQL이 실행된다.

예를 들어 주문이 10개라면

주문 조회 : 1번
회원 조회 : 10번

총 11번
 

이것이 N+1 문제이다.


해결 방법

필요한 연관 데이터를 처음부터 함께 조회한다.

 
@Query("""
SELECT o
FROM Order o
JOIN FETCH o.member
""")
List<Order> findAllWithMember();
 

또는

 
@EntityGraph(attributePaths = "member")
 

를 사용하여 한 번의 조회로 필요한 데이터를 가져올 수 있다.


★ 오늘 배운 점

  • Spring Bean은 스프링 컨테이너가 생성하고 관리하는 객체이다.
  • Bean 등록 방식에는 @Component와 @Configuration + @Bean이 있다.
  • Spring Bean은 기본적으로 Singleton으로 관리되므로 상태를 필드에 저장하지 않는 것이 중요하다.
  • JPA는 Repository → Spring Data JPA → JPA → Hibernate → DB 순서로 동작한다.
  • @Transactional에서는 Dirty Checking을 통해 save() 없이도 변경 사항이 반영된다.
  • LAZY 로딩은 성능 최적화에 유리하지만 N+1 문제가 발생할 수 있으며, Fetch Join이나 @EntityGraph를 사용해 해결할 수 있다.

'심화_AI를 활용한 백엔드 아키텍처 심화 과정' 카테고리의 다른 글

[내일배움캠프 사전캠프] 20회차 TIL(7/22 수) - Docker, Docker-Compose  (0) 2026.07.22
[내일배움캠프 사전캠프] 19회차 TIL(7/21 화) - Docker Image, Container  (0) 2026.07.21
[내일배움캠프 사전캠프] 17회차 TIL(7/15 수)  (0) 2026.07.15
[내일배움캠프 사전캠프] 16회차 TIL(7/14 화)  (0) 2026.07.14
[내일배움캠프 사전캠프] 15회차 TIL(7/10 금)  (0) 2026.07.10
'심화_AI를 활용한 백엔드 아키텍처 심화 과정' 카테고리의 다른 글
  • [내일배움캠프 사전캠프] 20회차 TIL(7/22 수) - Docker, Docker-Compose
  • [내일배움캠프 사전캠프] 19회차 TIL(7/21 화) - Docker Image, Container
  • [내일배움캠프 사전캠프] 17회차 TIL(7/15 수)
  • [내일배움캠프 사전캠프] 16회차 TIL(7/14 화)
taeyoon2
taeyoon2
taeyoon2 님의 블로그 입니다.
  • taeyoon2
    taeyoon2 님의 블로그
    taeyoon2
  • 전체
    오늘
    어제
    • 분류 전체보기 (36)
      • 심화_AI를 활용한 백엔드 아키텍처 심화 과정 (24)
      • MSA (11)
      • Study (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    api gateway
    내일배움캠프
    사전캠프
    분산추적
    Resilience4j
    RabbitMQ
    Zipkin
    보안구성
    심화_AI를 활용한 백엔드 아키텍처 심화 과정
    MSA
    내일배움캠프 #사전캠프 #til
    Config
    spring cloud
    서킷 브레이커
    JWT
    로드 밸런싱
    spring cloud config
    OAuth2
    이벤트 드리븐
    til
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
taeyoon2
[내일배움캠프 사전캠프] 18회차 TIL(7/16 목) - 스프링 컨테이너
상단으로

티스토리툴바