빈 등록 방법
@Configuration + @Bean 을 이용한 방법
@Configuration
public class GreetingConfig {
@Bean
Greeting englishGreeting() {
return new EnglishGreeting();
}
}
Component 를 이용한 방법
@Component
public class EnglishFarewell implements Farewell {
@Override
public void sayGoodBye() {
System.out.println("good bye");
}
}
@Configuration + @Bean vs @Component
- @Component 애너테이션은 클래스 레벨에서 사용되며, 해당 클래스의 인스턴스를 스프링 컨테이너가 관리하는 빈으로 등록한다. 주로 서비스, 레포지토리, 컨트롤러와 같은 스테레오타입 컴포넌트에 사용된다.
- @Configuration 애너테이션은 클래스가 하나 이상의 @Bean 메소드를 포함하고 있으며, 이 메소드들이 애플리케이션 컨텍스트에 Bean 정의를 제공한다는 것을 나타낸다. @Bean 메소드는 프로그래밍 방식으로 Bean 인스턴스를 생성하고 구성한다.
@Component는 클래스 자체를 Bean으로 등록하는 반면, @Configuration은 클래스 내의 @Bean 이 붙은 메소드를 통해 Bean을 정의하고 생성한다.
Spring Bean 객체의 생명주기 설정
Spring Bean 도 객체이므로 생성과 반환의 주기를 가지고 있다. 언제 초기화되고 언제 죽을지 설정할 수 있다.
- 생명주기 종류
- singleton: ApplicationContext가 시작될 때 초기화되고, ApplicationContext가 종료될 때 소멸됨. 이는 애플리케이션 전체에서 단 하나의 인스턴스만을 유지함을 의미
- prototype: 요청될 때마다 새로운 인스턴스가 생성. 생성된 각 인스턴스는 호출자에 의해 관리되며, Spring 컨테이너는 생성 이후에 이 인스턴스를 관리하지 않음
- request(web): HTTP 요청 하나가 들어오고 나갈 때 까지 유지되는 스코프, 각각의 HTTP 요청마다 별도의 빈 인스턴스가 생성되고, 관리된다.
- session(web): HTTP Session과 동일한 생명주기를 가지는 스코프
- application(web): 서블릿 컨텍스트( ServletContext )와 동일한 생명주기를 가지는 스코프
- websocket(web): 웹 소켓과 동일한 생명주기를 가지는 스코프
singleton pattern
prototype
prototype 의 경우 Bean 의 생성과 의존성 주입까지는 스프링 컨테이너에서 관리해주지만, 소멸은 관리해주지 않는다.
- Spring Bean 생명주기
스프링 IoC 컨테이너 생성 → 스프링 빈 생성 → 의존관계 주입 → (초기화 콜백 메소드 호출) → 사용 → (소멸 전 콜백 메소드 호출) → 스프링 종료
DI (Dependency Injection)
객체가 필요로 하는 의존성을 외부에서 직접 주입받는 것을 DI 라고 한다
Dependency Inversion Princlple (의존성 역전 원칙)
- 상위 모듈이 하위 모듈에 의존관계를 가지지 않도록 구현해야 한다는 원칙.
- 추상클래스는 그 구현체의 내용에 의존관계를 가지지 않는다.
- 구현체가 추상클래스에 의존관계를 가질 수 있다.
IoC (Inversion of Control)
- 프로그램의 흐름을 제어하는 주체가 프로그래머가 아닌 외부 시스템(예: 프레임워크)에 의해 결정된다는 개념
DIP 는 원칙이고, IoC 는 그 원칙을 지키기 위한 패턴이고, DI 는 그 패턴을 구현한 방법 중의 하나 이다.
@AutoWired 를 이용해서, 객체가 필요한 곳을 알려준다.
- Constructor Injection
- Setter Injection
- Field Injection
Constructor Injection
- 주입 받고 싶은 객체을 선언한다.
- 주입 받고 싶은 객체가 포함된 생성자를 선언한다.
- 롬복을 이용하면 생성자를 편하게 만들 수 있다. - @NoArgsConstructor: 인자를 포함하지 않는 생성자를 생성
- @RequiredArgsConstructor : final / non-nullfield argument 를 포함하는 생성자 자동 생성
- @AllArgsConstructor : 모든 argument 를 포함하는 생성자를 자동 생성
- 생성자가 단 하나일 경우는 @Autowired 가 붙은 생성자로 간주한다.
Setter Injection
- 주입 받고 싶은 객체을 선언한다.
- 주입 받고 싶은 객체의 세터를 생성한다.
- 세터에 @Autowired 를 붙여준다.
@Component
public class AppStartupRunner implements ApplicationRunner {
private Greeting greeting;
@Autowired
public void setGreeting(Greeting greeting) {
this.greeting = greeting;
}
@Override
public void run(ApplicationArguments args) {
greeting.sayHello();
}
}
Field Injection
- 주입 받고 싶은 객체을 선언한다.
- 주입 받고 싶은 객체에 @Autowired 를 붙여준다.
@Component
public class AppStartupRunner implements ApplicationRunner {
@Autowired
private Greeting greeting;
@Override
public void run(ApplicationArguments args) {
greeting.sayHello();
}
}
IDE(intellJ) 에서 생성자 주입을 권장하는 이유
- 의존성 주입의 명시성
생성자 파라미터로 필요한 의존성을 직접 전달받기 때문에 코드의 목적과 의도를 명확하게 드러난다. - 불변성 및 불변성 보장
생성자 주입은 한 번 설정되면 변경되지 않는 의존성을 보장. 이는 객체의 상태가 변경되지 않고 예측 가능하게 유지한다. - 테스트 용이성: 생성자 주입은 단위 테스트(Unit Test)를 수행할 때 의존성 주입을 쉽게 모의(Mock)할 수 있도록 함. 테스트 시 의존성을 직접 주입하여 원하는 동작을 테스트하기 용이하다.
- 코드의 안정성
생성자 주입은 컴파일 타임에 의존성을 확인하므로 런타임 시에 발생할 수 있는 오류를 사전에 방지할 수 있다. - Spring의 최신 권장사항
Spring 프레임워크는 최신 버전에서 생성자 주입을 권장. Spring Boot의 Auto Configuration 기능과의 호환성 및 편리성을 고려할 때 생성자 주입을 사용하는 것이 좋다.
'🚣활동 > NHN Academy' 카테고리의 다른 글
Spring AI로 알아보는 Java 기반 AI 엔지니어링 (0) | 2025.03.28 |
---|---|
Connection Pool 최적화 (0) | 2025.03.25 |
[Servlet & JSP] (0) | 2025.03.15 |
HTTPS (HTTP over SSL/TLS) (0) | 2025.02.17 |
쿠키와 세션 (Cookie & Session) (0) | 2025.02.17 |