멋쟁이사자처럼 13기/정기 세션

[멋사/Mac OS] 3주차 정기 세션 (Part 1. SpringBoot란?)

개발자 지망생 리네 2025. 6. 9. 17:53

정리하려고 보니 생각보다 내용이 방대하여 두 개의 게시글로 나누어서 정리할 예정이다.

먼저 SpringBoot에 대해 정리한다.

1. SpringBootApplication

- 스프링 부트 앱을 자동으로 설정해주는 핵심 어노테이션으로, 아래 세 가지가 합쳐졌다고 본다.

(1) @SpringBootConfiguration : 이 클래스가 설정 파일이라고 스프링에 알려주는 역할

(2) @EnableAutoConfiguration : 스프링 부트가 클래스패스에 있는 라이브러리를 보고 자동으로 설정을 적용함

-> spring-boot-starter-web이 있으면 Tomcat, DispatcherServlet 자동 등록

(3) @ComponentScan : Bean을 자동으로 스캔해서 등록

 

2. 내장 서버

- Tomcat과 같은 내장 서버를 제공하여 웹 애플리케이션을 쉽게 설정할 수 있음.

SpringApplication.run()

 

3. 스타터

- 특정 기능이나 라이브러리를 사용하기 위해 필요한 의존성들을 묶어서 제공

- spring-boot-starter-{작업유형} : 스프링부트가 기본적으로 제공하는 의존성 스타터의 명명 규칙

 

4. 의존성 주입(DI)

- 객체 간의 의존성을 외부에서 주입하는 방식

- 두 객체 간의 관계를 결정해주는 디자인 패턴

 

(1) 의존성 주입이 없는 경우

public class Engine {
    public void start() {
        System.out.println("엔진 가동!");
    }
}

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

    public void drive() {
        engine.start();
        System.out.println("달리는 중!");
    }
}

-> Car는 무조건 Engine만 사용 가능함

-> 만일 ElectricEngine, DieselEngine 같이 다른 엔진을 쓰고 싶으면 코드를 고쳐야하는 문제가 발생

 

 

(2) 의존성 주입이 있는 경우

public interface Engine {
    void start();
}

public class DieselEngine implements Engine {
    public void start() {
        System.out.println("디젤 엔진 가동!");
    }
}

public class ElectricEngine implements Engine {
    public void start() {
        System.out.println("전기 엔진 가동!");
    }
}

public class Car {
    private Engine engine;

    public Car(Engine engine) { // 생성자 주입
        this.engine = engine;
    }

    public void drive() {
        engine.start();
        System.out.println("달리는 중!");
    }
}
public class Main {
    public static void main(String[] args) {
        Engine diesel = new DieselEngine();
        Car myCar = new Car(diesel); // 디젤 엔진 장착

        myCar.drive();

        // 엔진 바꾸고 싶을 땐?
        Engine electric = new ElectricEngine();
        Car eCar = new Car(electric); // 전기 엔진 장착

        eCar.drive();
    }
}

-> 인터페이스에서 정의한 추상 메소드를 엔진 클래스에서 오버라이드하는 방식

-> Car는 Engine 인터페이스만 알면 되고, 실제 동작은 각 엔진 클래스가 알아서 구현

-> 유지 보수 용이

 

5. 스프링의 의존성 주입

(1) 생성자 코드 직접 입력

@Component
public class Car {

    private final Engine engine;

    @Autowired
    public Car(Engine engine) {
        this.engine = engine;
    }
}

 

(2) 롬복의 @RequiredArgsConstructor 사용 

@RequiredArgsConstructor
@Component
public class Car {

    private final Engine engine;
}

 

-> 컴파일 시 아래처럼 빈을 자동으로 주입해줌

public class Car {
    private final Engine engine;

    public Car(Engine engine) {
        this.engine = engine;
    }
}

 

(3) 필드 주입

@Component
public class Car {
    @Autowired
    private Engine engine;
}

-> 눈에 보이지 않아서 의존성이 숨겨짐

-> 테스트할 때 engine을 넣을 방법이 없어서 리플렉션 써야함

-> 실수로 null이 주입되어도 컴파일 타임에 잡아낼 수 없음

 

(4) SETTER 주입

@Component
public class Car {
    private Engine engine;

    @Autowired
    public void setEngine(Engine engine) {
        this.engine = engine;
    }
}

-> 외부에서 주입을 나중에 할 수 있음

-> 객체가 완전히 초기화되기 전에는 쓸 수 없음

 

6. 사용된 어노테이션

어노테이션 설명 사용처
@Component 해당 클래스를 스프링 빈으로 등록 Car, Engine, DieselEngine, ElectricEngine 
@Autowired 스프링이 해당 객체를 자동으로 주입 생성자, 필드, 세터에 사용 가능
@RequiredArgsConstructor final 필드를 기반으로 생성자 자동 생성 (롬복 어노테이션) 생성자 주입 간편화
@Configuration 자바 설정 클래스임을 명시 @Bean을 정의하는 클래스에 붙임
@Bean 수동으로 스프링 빈을 등록할 때 사용 @Configuration 안에서 메서드 위에 붙임
@Qualifier("이름") 같은 타입의 빈이 여러 개일 때 특정 빈을 명시적으로 선택 생성자/필드/세터 주입에 사용
@Primary 같은 타입의 빈이 여러 개일 때 우선 주입될 기본값 지정 클래스 위에 사용
@SpringBootApplication 스프링 부트 앱 시작점 + 자동 설정 + 컴포넌트 스캔 메인 클래스에 사용
@Override 자바에서 상속받은 메서드를 재정의했음을 명시 Engine 인터페이스 구현체에서 사용

 

7.  관점 지향 프로그래밍

(1) 제어의 역전(IoC)

- 개발자가 객체의 생명 주기를 직접 관리하지 않고, 프레임워크나 컨테이너가 객체의 생성과 관리를 대신 수행하는 것

- Spring Bean은 Spring Container가 생성하고 관리하는 객체를 의미하며, 보통 java 클래스가 Spring Bean으로 등록되어 관리된다.

- Spring Container는 Spring Bean의 생성과 관리를 담당하는 컨테이너로, 설정 정보를 기반으로 빈을 생성하고 의존성을 주입하며 생명주기를 관리한다.

 

(2) 관점 지향 프로그래밍(AOP)

- 공통 관심사를 핵심 로직에서 분리하여 따로 관리

-> AOP가 동작하기 위해서는 IoC가 필수적

-> 스프링이 객체를 생성하고 관리하면서 그 객체에 프록시를 씌워 AOP 기능을 덧붙이기 때문