Spring Boot/UMC

Chapter 4. Spring Boot 코어 개념

seung_hyeon 2025. 4. 9. 11:37

 

프레임워크

목적을 쉽게 달성할 수 있도록 해당 목적과 관련된 코드의 뼈대를 미리 만들어둔 것

 

Spring IoC 컨테이너

객체의 생성, 관리를 개발자가 아닌 Spring 프레임워크가 담당하는 개념

 

출처 : https://docs.spring.io/spring-framework/reference/core/beans/basics.html

 

작동방식

1. 객체를 class로 정의

2. 객체들 간의 연관성 지정 : 설정 파일(Config), 어노테이션으로 의존성 주입 지정

3. IoC 컨테이너가 이 정보를 바탕으로 객체 생성, 필요한 곳에 주입

 

IoC 컨테이너는 POJO 기반의 개발 가능하게 한다

( POJO : 복잡한 라이브러리, 프레임워크에 의존하지 않고 순수 자바 객체를 의미)

→ Spring은 POJO 기반의 개발을 지향 (프레임워크에 종속 X, 일반적인 자바 객체 사용)

 

Bean

Spring 컨테이너가 관리하는 자바의 객체

ApplicationContext.getBean() 호출 시 얻는 것이 Spring 빈

빈을 통해 객체 인스턴스화 후 객체 간의 의존 관계 관리

 

Bean으로 등록하여 관리하는 방식

1. @Component -> @Autowired : 묵시적 빈 정의 

- 클래스에 추가 후 @Autowired로 다른 클래스에서 해당 빈 끌어온다

 

2. @Configuration -> @Bean : 명시적 빈 정의 

- Spring 설정 파일에 @Configuration 추가 후 @Bean 붙여 명시적으로 빈 지정

 

  1. @Component 사용

클래스에 추가해서 Spring이 자동으로 해당 클래스 스캔하고 Bean으로 등록하도록 할 수 있다.

 

@Component
public class Member {
		private int age;
		private String name;
		
		public Member(){			
		}
		
		public Member(int age, String name) {
				this.age = age;
				this.nickname = name;
		}
}

 

@Component는 Spring이 자동으로 Member를 Bean으로 등록한다. ( 등록된 빈 스프링 컨테이너 안에 존재)

@Autowired는 등록된 빈을 가져와서 주입한다. 

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MemeberService {

    private final Member Member;

    @Autowired
    public MemberService(Member member) {
        this.Member = member;
    }

    public void printMemberInfo() {
        System.out.println("나이: " + member.getAge());
        System.out.println("너디나리 닉네임: " + member.getNickname());
    }
}

 

정리

@Component = 클래스 빈으로 등록

@Autowired = 등록된 빈 다른 곳에 주입

 


Spring DI(Dependency Injection)

의존성 주입 : 필요한 것 직접 만들지 않고, 필요한 걸 외부에서 주입하는 걸 의미

→ 한 갹체가 다른 객체 필요로 할 때 직접 만들지 않고 Spring이 대신 만들어 준다

 

 

  • 강한 결합(Tight Coupling)
public class Engine {
    public void start() {
        System.out.println("엔진이 켜졌습니다");
    }
}

public class Car {
    private Engine engine = new Engine();  // Car가 직접 Engine을 생성

    public void drive() {
        engine.start();
        System.out.println("자동차가 달립니다");
    }
}

 

  • 느슨한 결합 (Loose Coupling)
public interface Engine {
    void start();
}

public class GasolineEngine implements Engine {
    @Override
    public void start() {
        System.out.println("휘발유 엔진이 켜졌습니다!");
    }
}

public class ElectricEngine implements Engine {
    @Override
    public void start() {
        System.out.println("전기 엔진이 켜졌습니다!");
    }
}

 

@Override :  부모/인터페이스 메서드 다시 정의 

 


Spring의 의존성 주입 방식

1. 생성자 주입 (Constructor Injection) - 권장 방식!

2. setter 주입 (Setter Injection)

3. 필드 주입 (Field Injection)

 

  • 생성자 주입 (Constructor Injection)

의존성이 없는 객체 만들 수 없다

@Service
public class MemberService {
    private final MemberRepository memberRepository;

    @Autowired
    public MemberService(final MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
}

 

1. 필수값을 무조건 넣어야 한다

→ new MemberSignupService() 할 때 무조건 MemberRepository 만들어줘야 한다

리포지토리에 필요값도 같이 넣는다

 

2. 불변성

→ private final MemberRepository memberRepository;
final = 한번 주입되면 절대 바꿀 수 없다 

 

3. 테스트하기 쉽다

→ 가짜 PaymentService 넣어서 테스트하기 편하다

 

쉽게 말해서  생성자 주입은 초기화 때부터 필요한 부품을 다 조립해 놓는다

필요한 부품 없으면 생성 자체가 안되고 final을 사용해서 부품은 절대 바꿀 수 없다!

 

  • Setter 주입 (Setter Injection)

필요한 객체를 나중에 주입하는 방법

런타임에 의존성 주입하기 때문에 의존성 없더라도 객체 생성 가능하다

 

@Service
public class MemberService {
	private final MemberRepository memberRepository;
	
	@Autowired
	public void setMemberService(final MemberRepository memberRepository) {
			this.memberRepository = memberRepository;
	}
}

 

 

new setMemberService() 때 memberRepository 만들어지지만 값은 null

나중에 setMemberService() 메서드 호출 시 채워진다

NullPointException 에러 발생할 수 있다!

 

  • 필드 주입(Field Injection)

런타임에 의존성 주입하기 때문에 의존성 없더라도 객체 생성 가능하다

 

@Service
public class MemberService {
    @Autowired
    private MemberRepository memberRepository;
}

 

필드에 직접 주입된다 

의존성 관계가 드러나지 않아 순환 참조 문제 발생할 수 있다!

 


Spring Servlet

Spring MVC 패턴에서 Controller에 해당하는 부분

 

Servlet 

웹 애플리케이션에서 클라이언트의 요청 처리, 그에 대한 응답 생성하는 구성 요소

→ 자바에서 웹 만들 때 HTTP 요청 처리하는 친구

 

서블릿 필요한 이유

웹은 요청 ↔ 응답 흐름으로 작동한다

이 중간에서의 흐름을 자바로 직접 컨트롤하려면 서블릿이 꼭! 필요하다

(서블릿이 없으면 자바는 웹 요청을 직접 받을 수 없다)

 

Servlet Container

Servlet 관리해 주는 컨테이너 역할

 

- 클라이언트의 요청 받고 응답할 수 있게 웹 서버, Socket으로 통신

- Socket 통신을 전부 자동으로 처리해 준다

 

요청 처리 방법

 

1. web.xml기반으로 사용자가 요청한 URL이 어느 서블릿에 대한 요청인지 찾는다

 

2. 서블릿이 메모리에 없을 경우 -  init()을 통해 생성

    서블릿 변경 - destory() → init()

    서블릿 있는 경우 - service() 메서드 호출 (Get → doGet( ) / POST → doPost() )

 

3. 응답 브라우저로 돌려보낸다

 

4. 서버 종료 시에는 destory() 메서드 호출하여 메모리에 깨끗이 제거

 

 

DispatcherServelt

Spring에서 가장 중요한 서블릿

- Front Controller 패턴을 구현한 서블릿 / 모든 HTTP 요청받는다

 

 

 

'Spring Boot > UMC' 카테고리의 다른 글

Chapter 3. API  (0) 2025.04.01
Chapter 2. 실전 SQL  (0) 2025.03.27