Back-End

[Spring] 기초 공부

Minch13r 2025. 4. 15. 18:41

Spring 프레임워크란 무엇인가?

Spring은 자바 기반의 애플리케이션 개발을 위한 오픈소스 프레임워크.

마치 레고 블록처럼 다양한 기능들을 쉽게 조립하여 사용할 수 있게 도와주는 도구.

Spring의 주요 특징

  1. 경량 컨테이너: 애플리케이션의 객체를 생성하고 관리.
  2. POJO 기반: Plain Old Java Object를 사용하여 개발 가능.
  3. IoC/DI 지원: 객체 간의 의존성을 관리.
  4. AOP 지원: 공통 기능을 분리하여 모듈화.
  5. 트랜잭션 관리: 데이터베이스 트랜잭션을 쉽게 관리.

IoC(Inversion of Control, 제어의 역전)란?

IoC는 '제어의 역전'이라는 의미로, 프로그램의 제어 흐름을 개발자가 아닌 프레임워크가 관리하는 것을 의미.

쉬운 예시로 이해하기

일반적인 프로그래밍에서는 개발자가 직접 객체를 생성하고 메서드를 호출:

// 개발자가 직접 객체 생성
UserService userService = new UserService();
userService.registerUser();

 

하지만 IoC에서는 이 제어권이 Spring 컨테이너로 넘어감:

// Spring이 객체를 생성하고 관리
// 개발자는 단지 사용만 함
@Autowired
private UserService userService;
userService.registerUser();

IoC의 장점

  1. 코드의 결합도 감소: 객체 간의 의존성이 줄어듦.
  2. 유지보수성 향상: 코드 변경이 필요할 때 영향 범위가 줄어듦.
  3. 테스트 용이성: 각 컴포넌트를 독립적으로 테스트하기 쉬워짐.

DI(Dependency Injection, 의존성 주입)란?

DI는 IoC를 구현하는 방법 중 하나로, 객체가 필요로 하는 의존성을 외부에서 주입해주는 패턴을 의미.

의존성 주입의 종류

생성자 주입(Constructor Injection)

public class UserService {
    private final UserRepository userRepository;
    
    // 생성자를 통한 주입
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

 

세터 주입(Setter Injection)

public class UserService {
    private UserRepository userRepository;
    
    // 세터를 통한 주입
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

 

필드 주입(Field Injection)

public class UserService {
    // 필드에 직접 주입
    @Autowired
    private UserRepository userRepository;
}

DI의 장점

  1. 코드 재사용성 증가: 동일한 인터페이스를 구현한 다른 객체로 쉽게 교체 가능.
  2. 단일 책임 원칙 준수: 각 클래스는 자신의 역할에만 집중 가능.
  3. 테스트 용이성: 목(Mock) 객체를 주입하여 테스트하기 쉬워짐.

@Component 어노테이션

@Component는 Spring에서 관리되는 객체(Bean)임을 나타내는 기본 어노테이션. Spring은 @Component가 붙은 클래스를 찾아 자동으로 Bean으로 등록.

@Component의 특수화된 어노테이션들

  1. @Controller: 웹 요청을 처리하는 컨트롤러 클래스에 사용.
  2. @Service: 비즈니스 로직을 처리하는 서비스 클래스에 사용.
  3. @Repository: 데이터 접근 계층(DAO)에 사용.

이 세 가지 어노테이션은 모두 @Component를 포함하고 있지만, 각각의 역할을 명확히 하기 위해 사용.

사용 예시

@Component
public class EmailService {
    public void sendEmail(String to, String subject, String body) {
        // 이메일 전송 로직
    }
}

@Service
public class UserService {
    // 사용자 관련 비즈니스 로직
}

@Repository
public class UserRepository {
    // 데이터베이스 접근 로직
}

@Controller
public class UserController {
    // 웹 요청 처리 로직
}

@Autowired 어노테이션

@Autowired는 Spring이 자동으로 의존성을 주입해주는 어노테이션. Spring 컨테이너는 @Autowired가 붙은 필드, 생성자, 메서드에 적절한 Bean을 찾아 주입.

사용 위치에 따른 @Autowired

필드 주입

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
}

 

생성자 주입

@Service
public class UserService {
    private final UserRepository userRepository;
    
    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

 

세터 주입

@Service
public class UserService {
    private UserRepository userRepository;
    
    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

@Autowired의 동작 원리

  1. Spring은 애플리케이션 컨텍스트에서 주입하려는 필드와 타입이 일치하는 Bean을 찾음.
  2. 일치하는 Bean이 하나만 있으면 해당 Bean을 주입.
  3. 일치하는 Bean이 없으면 오류가 발생(required=false 옵션으로 변경 가능).
  4. 일치하는 Bean이 여러 개라면 @Qualifier 어노테이션을 사용하여 특정 Bean을 지정해야 함.
@Autowired
@Qualifier("emailNotificationService")
private NotificationService notificationService;

IoC, DI, @Component, @Autowired의 관계

이 네 가지 개념은 Spring의 핵심을 이루는 요소들로, 다음과 같은 관계를 가짐:

  1. IoC: Spring의 핵심 원리로, 객체 생성과 생명주기 관리를 Spring이 담당.
  2. DI: IoC를 구현하는 디자인 패턴으로, 객체 간의 의존성을 외부에서 주입.
  3. @Component: Spring이 관리할 Bean으로 클래스를 등록하는 어노테이션.
  4. @Autowired: Spring이 자동으로 의존성을 주입하는 어노테이션.

실제 동작 과정

  1. @Component가 붙은 클래스를 Spring이 스캔하여 Bean으로 등록.
  2. @Autowired가 붙은 위치에 적절한 Bean을 찾아 주입.
  3. 이 과정을 통해 IoC와 DI가 구현.

'Back-End' 카테고리의 다른 글

[Spring] 어노테이션 정리  (1) 2025.04.20
[Spring] 기초 공부1  (1) 2025.04.19
JDBC와 JPA  (1) 2025.04.07
[JAVA] JSTL이란?  (2) 2025.03.19
[API] 자주 쓰는 API 정리  (4) 2025.03.11