스프링 프레임워크 기본(spring)

topics 300-백엔드개발 301 Spring
types 이론 학습
tags

3tier 서버

클라이언트 (webserver)
웹어플리케이션서버 (WAS)
데이터베이스 서버

framework와 library차이
제어의 역전!! 제어가 누가 하냐

특징

  • POJO(Plain Old Java Object)기반 구성 : 객체 지향적인 원리에 충실하면서 환경과 기술에 종속되지 않고 필요에 따라 재활용될 수 있는 방식으로 설계된 오브젝트이다.
  • 제어의 역행(IoC)과 의존성 주입(DI)를 통한 객체간의 구성
  • AOP(관점 지향 프로그래밍) 지원
    • 종단(핵심)관심사 : 비즈니스
      • 장점 : 순수 비즈니스 코드만 작성 가능
    • 횡단관심사 : 공통관심사
      • 중복 제거, 유지보수 굿
      • aspect : 어떤 부가기능을 어디에 적용할지 정의한 것
        • 횡단관심사를 캡슐화
        • advice : aspect에서 적용되는 메서드
        • join point : aspect가 적용되는 시점
          • 종단횡단의 교차라고 생각하면 될 듯?
구분 횡단 관심사(Cross-Cutting Concerns) 핵심 관심사(Core Concerns)
특징 여러 모듈·계층에 걸쳐 반복적으로 등장하는 부가 기능 애플리케이션의 주요 비즈니스 로직
예시 로깅, 보안, 트랜잭션, 예외 처리, 성능 모니터링 사용자 주문 처리, 결제 로직, 상품 관리
관리 방식 AOP를 통해 모듈화하여 한 곳에서 관리 각 비즈니스 모듈에서 독립적으로 구현
코드 중복 중복 발생 → AOP로 해결 중복 없음
변경 영향도 한 번의 수정으로 전체 적용 가능 해당 모듈만 수정하면 됨
아키텍처-1747921913860.png

주요 요소

  • 빈(Bean) : 스프링 컨테이너가 관리하는 자바 객체이다.
    • 기본적으로 싱글톤 방식
    • 수동으로 등록 방법
      • 설정 클래스 파일을 만들어 @Configuration 적용
      • 빈으로 등록할 메서드에 대해 @Bean 적용
  • 스프링 컨테이너(Spring Container) : 스프링에서 빈 객체들을 관리하는 공간이다.
    • 빈 팩토리라고도 부름
      • 빈 팩토리를 부모로 갖는 ApplicationContext 도 있다.
        • 부가기능을 추가로 제공함
      • 굳이 따지자면 이렇게 두 개로 나눌 수 있음
    • 스프링 컨테이너는 빈(Bean)의 생성부터 소멸까지 개발자 대신 관리해준다.
    • 스프링 컨테이너에 객체, 빈(Bean)을 등록하는 이유는 객체간의 의존 관계들을 스프링이 관리하도록 하기 위해서다.

쓰는 기술

  • 핵심 기술 : 스프링 IoC 컨테이너, AOP , 기타 등등
  • 웹 기술 : 스프링 MVC , 스프링 WebFlux
  • 데이터 접근 기술 : 트랜잭션, JDBC, ORM
  • 테스트 : 스프링 기반 테스트 지원 등등

solid

https://velog.io/@haero_kim/SOLID-%EC%9B%90%EC%B9%99-%EC%96%B4%EB%A0%B5%EC%A7%80-%EC%95%8A%EB%8B%A4

SRP 단일책임

응집도는 높게 결합도는 낮게

isp 인터페이스 분리 원칙

클라이언트의 목적과 용도에 적합한 인터페이스만을 제공하기 위해 인터페이스를 잘게 분리하는 것

의존성 주입 DI

생성자 주입

@Service
public class OrderService {
    private final OrderRepository repository;

    // 생성자 주입
    @Autowired // (생성자가 하나면 생략 가능)
    public OrderService(OrderRepository repository) {
        this.repository = repository;
    }
}
  • final : 불변성 보장
  • 생성시 한번만 호출됨(싱글톤으로써서)
  • 불변과 필수 의존관계

필드 주입

@Service
public class OrderService {
    @Autowired
    private OrderRepository repository;
}

스프링의 객체(빈) 관리 vs. 가비지 컬렉터(GC)

구분 스프링 빈 관리 가비지 컬렉터(GC)
관리 주체 스프링 컨테이너 JVM(자바 가상 머신)
관리 대상 스프링 컨테이너에 등록된 객체(빈) 모든 자바 객체(참조가 끊긴 객체)
주요 역할 객체의 생성, 의존성 주입, 초기화/소멸 콜백 관리 사용하지 않는 객체의 메모리 자동 해제
생명주기 제어 개발자가 초기화·소멸 시점에 직접 개입 가능 참조가 끊긴 시점에 JVM이 자동으로 처리
콜백 지원 @PostConstruct, @PreDestroy 등으로 명확한 콜백 제공 별도의 콜백 없음
현재까지내가느끼기에는 싱글톤을 관리하고자 생긴느낌?
싱글톤일때의 주기를제어하기 위해생긴

헷갈리는 것

빈 : 구현체
서비스 : 인터페이스

빈과 서비스는 보통 1대1매칭함 이럴경우 자동으로 스프링이 타입기반으로 주입

이건 필드주입임

Q 스프링에서 필드 주입을 안 하고 final을 씀으로서 얻는 이득이 뭔데

여기서의 final을 쓴다 = 생성자 주입을 말함

  1. 불변성(immutability) 보장
    final로 선언된 필드는 한 번만 값이 할당되고, 이후에는 변경이 불가능하다.

생성자 주입을 사용하면 객체가 생성될 때 반드시 의존성이 할당되어야 하므로,
런타임 동안 의존 객체가 바뀌는 일이 없어 안정적이다.

  1. 필수 의존성 보장
    final을 사용하면, 그 필드는 반드시 생성자에서 값을 받아야 한다.

즉, 의존성이 누락될 가능성을 컴파일 시점에 차단할 수 있다.

필드 주입/세터 주입은 의존성을 빼먹어도 컴파일 에러가 나지 않지만,
생성자 주입 + final은 누락 시 컴파일 에러가 발생한다.

  1. 테스트 용이성
    생성자 주입은 스프링 컨테이너 없이도,
    직접 new로 객체를 만들며 원하는 의존 객체를 주입할 수 있다.

반면 필드 주입은 리플렉션 등 복잡한 방법을 써야 하므로 테스트가 불편하다.

  1. 순환 참조/초기화 문제 예방
    생성자 주입은 객체 생성 시점에 의존성이 모두 주입되어야 하므로,
    순환 참조나 누락된 의존성을 애플리케이션 시작 시점에 바로 발견할 수 있다.

필드 주입은 객체 생성 후에 주입이 이뤄지기 때문에,
런타임에야 문제가 드러나거나, 순환 참조가 감지되지 않을 수 있다.

  1. 코드 명확성, 유지보수성 향상
    생성자 파라미터로 의존성을 모두 명시하므로,
    이 클래스가 무엇에 의존하는지 한눈에 파악할 수 있다.

final을 쓰면, "이 의존성은 반드시 필요하다"는 의도를 명확히 드러냅니다

1. 인터페이스 1개 + 구현체 1개 (가장 흔함)

  • 대부분의 서비스/레포지토리 구조는 이렇게 설계한다.
  • 예시:
public interface OrderRepository { ... } 
@Repository 
public class JpaOrderRepository implements OrderRepository { ... }
  • 이 경우, 스프링이 자동으로 1:1로 매칭해서 주입해준다.
  • 대부분의 실무 프로젝트에서 가장 많이 보는 구조이다.

2. 인터페이스 1개 + 구현체 여러개(특수한 경우)

  • 예외적으로, 테스트용/특수 상황용 구현체가 추가될 수 있다.
  • 예시:
    @Repository 
    public class MemoryOrderRepository implements OrderRepository { ... } 
    
    @Repository public class JpaOrderRepository implements OrderRepository { ... }
    
  • 이때는 @Primary나 @Qualifier로 어떤 구현체를 쓸지 명확히 지정해야 한다.
  • 이런 경우는 비교적 드물고, 테스트나 확장성 목적에서만 일부러 두는 경우가 많다.