2024.07.17 - [Spring] - [Spring] 스프링 빈과 의존관계-컴포넌트 스캔으로 의존관계 설정(1)
[Spring] 스프링 빈과 의존관계-컴포넌트 스캔으로 의존관계 설정(1)
📍스프링 빈과 의존관계 이번 시간에는 저번 포스팅에서 진행했던 유저 관리 로직을 프론트엔드와 같이 엮어 보려고 한다. 이때, 필요한것은 유저 컨트롤러와 뷰 템플릿이다. 그럴려면, 멤버
jghdg1234.tistory.com
이전 포스팅에는 어노테이션을 활용해 자동으로 의존 관계를 설정 해주었다. 다시 기억해 보자면... Raw 자바 코드는 Spring인지 아닌지 알 수 없으므로 @Service라는 어노테이션을 추가 해야하고, 또한, 의존성 주입을 위해 생성자 위에 @Autowired 라는 어노테이션을 추가 해야하고, 저장소에는 @Repository라는 어노테이션 등을 추가 해야한다.
그렇지만 이번에는, 어노테이션이 아니라 자바 코드로 직접 스프링 빈을 등록하는 방법을 알아보자.
먼저, src/main/java/Jihoo.hello_spring 에다가 SpringConfig라는 파일을 하나 만들어 준다.
package Jihoo.hello_spring;
import Jihoo.hello_spring.service.MemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService();
}
}
이렇게 작성이 되면, 스프링이 시작될때 @Configuration 어노테이션과 그 안의 @Bean을 읽고, 스프링 빈에 객체를 등록 해준다.
하지만 MemverService의 생성자는 memberRepository를 인자로 받는다. 그 말은 memberRepository도 스프링 빈에 등록이 되어야 한다. 아래와 같이 memberRepository도 빈으로 생성을 해준 후, memberService의 파라미터로 던져준다.
package Jihoo.hello_spring;
import Jihoo.hello_spring.repository.MemberRepository;
import Jihoo.hello_spring.repository.MemoryMemberRepository;
import Jihoo.hello_spring.service.MemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
- MemberService와 MemberRepository를 모두 스프링 빈에 등록 한 후, 스프링 빈에 등록되어있는 memberRepo를 memberService에 넣어준다.
이렇게 하면 이전 포스팅에서 본 그림과 같이 서로 의존 관계가 형성이 되었다. 의존 관계는 실행중에 동적으로 변하는 경우는 거의 없으므로 생성자 주입을 권장한다.
다시 모든 내용을 정리하자면....
스프링 빈 (Spring Bean)이란?
스프링 빈은 스프링 애플리케이션 컨텍스트가 관리하는 자바 객체이다. 스프링 빈은 스프링 컨테이너에 의해 생성되고 관리된다. 스프링 프레임워크는 의존성 주입(Dependency Injection)을 통해 빈들의 생명주기를 관리하며, 애플리케이션의 컴포넌트 간 결합도를 낮추어 유지보수성과 테스트 용이성을 높여준다.
스프링에서는 의존성을 주입하는 방식으로 두 가지 주요 접근 방법이 있다:
1. 컴포넌트 스캔 방식 (Component Scan)
2. 직접 자바 코드로 설정하는 방식 (Java Configuration)
1. 컴포넌트 스캔 방식 (Component Scan)
스프링의 컴포넌트 스캔은 클래스에 어노테이션을 붙여 스프링 빈으로 등록하는 방식이다.
주로 `@Component`, `@Service`, `@Repository`, `@Controller`와 같은 어노테이션을 사용한다.
장점:
- 코드가 간결해지고, 설정이 쉽다.
- 클래스 파일만으로 구성 요소를 쉽게 식별할 수 있다.
단점:
- 자동으로 스캔되기 때문에 클래스 경로 내의 모든 어노테이션이 스캔되어 빈으로 등록된다.
- 어노테이션을 사용하므로 코드의 가독성이 떨어질 수 있다.
예제:
import org.springframework.stereotype.Service;
@Service
public class MemberService {
// 서비스 로직
}
위 예제에서 `@Service` 어노테이션을 사용하여 `MemberService` 클래스가 스프링 빈으로 등록된다.
설정:
스프링 부트에서는 `@SpringBootApplication` 어노테이션이 포함된 클래스가 있는 패키지와 그 하위 패키지를 자동으로 스캔한다.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HelloSpringApplication {
public static void main(String[] args) {
SpringApplication.run(HelloSpringApplication.class, args);
}
}
2. 직접 자바 코드로 설정하는 방식 (Java Configuration)
이 방식은 자바 클래스를 사용하여 스프링 빈을 명시적으로 등록하는 방식이다. 주로 `@Configuration`과 `@Bean` 어노테이션을 사용한다.
장점:
- 빈의 생성과 설정을 명확하게 제어할 수 있다.
- 코드 기반 설정으로 더 많은 유연성과 가독성을 제공한다.
단점:
- 설정 클래스와 메서드를 따로 작성해야 하므로 설정 파일이 많아질 수 있다.
- 컴포넌트 스캔에 비해 초기 설정 작업이 더 많다.
예제:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberService();
}
}
위 예제에서 `@Configuration` 어노테이션이 붙은 `AppConfig` 클래스는 스프링 설정 클래스임을 나타내며, `@Bean` 어노테이션을 사용하여 `memberService` 메서드가 반환하는 객체를 스프링 빈으로 등록한다.
설정:
스프링 부트에서 자바 설정 클래스를 사용하려면, 애플리케이션 시작 클래스에서 `@SpringBootApplication` 어노테이션과 함께 사용된다.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;
@SpringBootApplication
@Import(AppConfig.class) // Java 설정 클래스 임포트
public class HelloSpringApplication {
public static void main(String[] args) {
SpringApplication.run(HelloSpringApplication.class, args);
}
}
의존성 주입 방식의 차이점
컴포넌트 스캔 방식:
- 주로 어노테이션(`@Component`, `@Service`, 등)을 사용
- 설정이 간단하고 코드가 간결해짐
- 자동으로 스캔하여 빈을 등록
- 자동 스캔의 범위를 제어하기 어려움
- 스프링 부트의 `@SpringBootApplication`이 자동 스캔을 수행
자바 코드 설정 방식:
- 주로 자바 설정 클래스(`@Configuration` + `@Bean`)을 사용
- 설정과 생성을 명확하게 제어할 수 있음
- 명시적으로 빈을 등록
- 설정 파일을 통해 관리 범위를 명확히 할 수 있음
- 설정 클래스를 `@Import`를 통해 명시적으로 포함
작은 프로젝트에서는 컴포넌트 스캔 방식을, 복잡한 설정이 필요한 경우에는 자바 코드 설정 방식을 사용하는 것이 일반적이다.
'Spring' 카테고리의 다른 글
[Spring] 스프링 빈과 의존관계-컴포넌트 스캔으로 의존관계 설정(1) (4) | 2024.07.17 |
---|---|
[Spring]회원 관리 - 백엔드 개발 (0) | 2024.07.12 |
[Spring] 어노테이션이란 무엇일까? (0) | 2024.07.11 |
[Spring]웹 개발 기초 - 정적 컨텐츠, MVC, 템플릿, API (0) | 2024.07.11 |
[Spring] 정적페이지 띄우기, 템플릿 엔진 동작법 (1) | 2024.07.10 |