본문 바로가기

Java/Spring

(Spring) - 객체 생명주기

반응형

🍳머리말

객체 생명주기는 앱의 확장성, 안정성에 중요합니다. 어떻게 관리하는지에 대해 알아봅니다.


📕 정의

📔  객체

프로그램에서 데이터와 데이터를 처리하는 메서드를 하나로 묶은 독립적 단위

📔  객체 생명주기란

객체가 생성, 초기화, 소멸 되는 전 과정을 의미. Spring에서는 IoC 컨테이너가 객체 생명주기를 관리하며 개발자가 이 과정을 직접 처리하지 않아도 되도록 지원


📕 주요 특징

📔 객체 생명주기 단계

📑 컨테이너 초기화

  • ApplicationContext가 초기화되면서 XML 설정 파일, Java config 클래스, 또는 어노테이션 스캔을 통해 Bean 정보 읽음
  • 객체 클래스 의존성 초기화/소멸 메서드 포함

📑 생성

  • IoC 컨테이너가 @Component, @Bean 또는 XML에 정의된 bean을 찾아 생성
  • Scope에 따라 생성 시점이 달라질 수 있음
    • Singleton(기본) : 컨테이너당 하나의 인스턴스를 생성
    • Prototype : 요청 시마다 생성

📑 의존성 주입

  • Bean이 생성된 후 IoC컨테이너가 객체에 필요한 의존성을 주입
    • 생성자 주입, 필드 주입, Setter 주입
  • 객체간의 결합도를 낮추고 응집도를 증가

📑 초기화

  • Bean생성 완료하고 의존성 모두 주입 후, 다음 방법으로 초기화 작업 진행

 

  • @PostConstruct
@PostConstruct
public void init() {
  System.out.println("Bean is initialized!");
}

 

  • InitilizingBean 인터페이스
@Override
public void afterPropertiesSet() {
  System.out.println("InitializingBean method called!");
}

 

  • XML / Java Config에서 init-method 설정
<bean id="exampleBean" class="com.example.MyBean" init-method="customInitMethod" />

📑 사용

  • 요청 처리, 서비스 호출 등 Bean을 앱 로직내에서 사용

📑 소멸

  • IoC 컨테이너 종료시 소멸 작업시작. 다음 방법 중 하나로 구현

 

  • @Predestroy
@PreDestroy
public void destroy() {
  System.out.println("Bean is being destroyed!");
}

 

  • DisposableBean 인터페이스
@Override
public void destroy() {
  System.out.println("DisposableBean method called!");
}

 

  • XML / Java config에서 destroy-method 설정
<bean id="exampleBean" class="com.example.MyBean" destroy-method="customDestroyMethod" />

 

📔 Scope

Spring IoC 컨테이너는 객체의 생명주기를 scope로 관리. 다음과 같은 종류가 있음.

 

📑 Singleton(기본)

컨테이너당 하나의 인스턴스를 생성

 

📑 Prototype

요청마다 새로운 인스턴스를 생성

📘 예시

@Component
@Scope("prototype")
public class PrototypeBean {
  public void doSomething() {
    System.out.println("Prototype instance");
  }
}

 

📑 Request, session, application 등 웹 관련

 


📕 실무 사용 예제와 그 이유

📔 초기화와 소멸 메서드 사용 이유

  • 외부 리소스 연결, 캐시 초기화 등 Bean이 사용할 준비완료를 위해 초기화 메서드 사용
  • 파일 닫기, 네트워크 연결 종료, 캐시 해제 등 리소스 해제를 위해 소멸 메서드 사용

📘 예시

@Component
public class ResourceBean {

  @PostConstruct
  public void init() {
    System.out.println("Resource initialized.");
  }

  @PreDestroy
  public void cleanup() {
    System.out.println("Resource cleaned up.");
  }
}

📕 장단점

항목 IoC컨테이너 사용 미사용
객체 생성 IoC컨테이너가 객체 생성, 관리 개발자가 객체 생성, 관리
의존성 관리 컨테이너가 의존성 주입
@Autowired, @Inject
개발자가 직접 객체 간 연결
생명주기 관리 초기와, 소멸 메서드 자동 호출 개발자가 수동 호출
코드 복잡도 간결화 복잡
결합도 낮음 높음
확장성 높음 낮음
테스트 용이성 Mock객체 활용해 용이 Mock 객체 활용 어려움
초기 설정 초기 학습 비용 필요 설정 없이 바로 구현 가능
실행 시 성능 컨테이너 초기화 시 오버헤드 초기화 속도 빠름

📕 새로운 트렌드

📔 경량 DI 컨테이너

  • Micronaut와 Ktor같은 프레임워크는 컴파일 타임 DI 사용해 Spring보다 빠른 실행 속도와 낮은 메모리 사용량 제공

📘 예시(Micronaut)

@Factory
public class AppModule {
  @Singleton
  public MyService myService(MyRepository myRepository) {
    return new MyService(myRepository);
  }
}

 

📘 예시(Ktor)

val myModule = DI.Module("myModule") {
  bind<MyService>() with singleton { MyService(instance()) }
  bind<MyRepository>() with singleton { MyRepository() }
}

 


📕참조

Spring 공식 문서


*더 나은 내용을 위한 지적, 조언은 언제나 환영합니다.

'Java > Spring' 카테고리의 다른 글

OSIV란 무엇인가?  (0) 2024.11.22