[CS_study] 스프링의 주요 특징

JUN·2024년 11월 20일
0

CS

목록 보기
4/6

스프링의 주요 특징은 5가지이다.

  1. POJO 기반의 구성
  2. 의존성 주입을 통한 객체간의 관계 구성
  3. AOP 지원
  4. 편리한 MVC 구조
  5. WAS 에 종속적이지 않은 개발 환경

POJO 기반의 구성

스프링은 객체간의 관계를 구성할 때에 별도의 API를 사용하지 않고 POJO의 구성만으로 가능하다.

즉. 일반적인 JAVA코드를 사용하여 객체간의 관계를 구성하기에 JAVA를 배울 때에 썼던 가장 일반적인 형태의 코드를 그대로 실행할 수 있다는 것이 장점이다.

POJO 객체를 사용하면 좋은점.

특정한 라이브러리나 컨테이너의 기술에 종속적이지 않기에 가장 일반적인 JAVA코드로 실행할 수 있어 생산성과 테스트코드 작업에 유리하다.

의존성 주입(DI)

한 객체가 다른 객체를 필요로 할 때에 해당 객체를 직접 생성하는 것이 아닌, 외부로부터 주입을 받을 수 있다.

이 경우 각 객체는 자신의 역할에 집중할 수 있다. 어떤 객체에 의존하든 자신의 역할은 변경되지 않는다는 것이다.

스프링에서는 Application Context 가 필요한 객체들을 생성하고 필요한 객체들을 주입하는 역할을 한다.

Application Context 가 객체들을 관리하고 해당 객체와 객체사이의 의존관계를 설정할 수 있다. (이 객체를 Bean이라고 부른다.)

해당 Bean을 등록하는 방식으로

  1. XML 설정
  2. 어노테이션 설정
  3. JAVA 설정

방식이 있다. 각 객체들은 기본적으로 싱글톤 객체로 생성이 되며 객체들의 의존성을 Application Context 가 관리하게 된다.

스프링 Bean의 종류

AOP 지원

기본적으로, 프레임워크는 개발자가 비즈니스 로직에만 집중할 수 있게 발전해왔다.

이를 실현하기 가장 좋은 방법이 반복적인 코드의 제거 이다.

스프링에서는 대부분의 시스템이 공통으로 가지고 있는 보안, 로그, 트랜잭션과 같은 비즈니스 로직이 아니지만 반드시 처리가 필요한 부분들을 가지고 있고 이를 횡단 관심사 라고 부른다.

이러한 횡단 관심사를 모듈로 분리해서 제작하는 것이 AOP(관점 지향 프로그래밍) 이다.

스프링에서는 AspectJ의 문법을 통해서 AOP 를 작성할 수 있다.

장점

  • 핵심 비즈니스 로직에만 개발자가 집중할 수 있음
  • 각 프로젝트마다 다른 관심사를 적용할 때 코드의 수정을 최소화 시킬 수 있음
  • 원하는 관심사의 유지보수가 수월한 코드를 구성할 수 있음
  1. AspectJ:
  • 모든 Join Point(메서드 실행, 필드 접근, 객체 생성 등)를 지원한다.
  • 컴파일 시 위빙이 가능해 실행 성능이 우수하다.
  • 객체지향 프로그래밍의 모든 부분에 AOP를 적용할 수 있다.
  1. Spring AOP:
  • 메서드 실행 Join Point만 지원하며, 필드 접근이나 객체 생성에는 적용할 수 없다.
  • 프록시 기반 런타임 위빙만 지원해 실행 성능이 AspectJ보다 다소 낮다.
  • Spring의 DI 컨테이너와 통합되어 AOP 사용이 간편하다.

AspectJ 의 작동 방식

  1. 포인트컷(Pointcut) 정의: 어떤 메서드에 관심사를 적용할지 지정
    • 횡단 관심사가 실행되는 실행 시점을 선택한다.
      // com.example.service 패키지의 모든 메서드 실행 시점을 포인트컷으로 정의하는 예시
      @Pointcut("execution(* com.example.service.*.*(..))")
      public void serviceLayerMethods() {}
    • 주요 포인트컷 유형
      • execution() : 메서드 실행 시점 지정
      • within() : 특정 클래스나 패키지 내부의 모든 메서드 지정
      • this/target : this는 프록시 객체 기준, target은 실제 대상 객체 기준으로 포인트컷을 적용
      • args() : 특정 파라미터 타입에 대해 적용
  2. 어드바이스(Advice) 정의: 적용할 공통 기능(관심사)을 정의
    • 즉 포인트컷부터 선택된 지점에 실행할 횡단 관심사의 기능을 정의하는 부분이다.
    • AspectJ는 어드바이스의 실행 시점을 기준으로 5가지 유형으로 분류한다.
      • @Before(): 메서드 실행 전에 어드바이스를 실행
      • @After(): 메서드 실행 후에 어드바이스를 실행 (예외 발생 여부와 관계없이)
      • @AfterReturning(): 메서드가 정상적으로 실행된 후에 어드바이스를 실행
      • @AfterThrowing(): 메서드 실행 중 예외가 발생했을 때 어드바이스를 실행
      • @Around(): 메서드 실행 전후에 어드바이스를 실행, 가장 강력한 어드바이스 유형
  3. 위빙(Weaving): 포인트컷에 지정된 지점에 어드바이스를 삽입하는 과정
    • AspectJ는 컴파일 시점, 클래스 로드 시점, 런타임 시점으로 위빙을 수행한다.
    • 컴파일 시 위빙(Compile-time Weaving):
      • AspectJ 컴파일러(ajc)를 사용하여 소스 코드 컴파일 시 어드바이스를 삽입한다.
      • 결과적으로 바이트코드에 AOP 로직이 포함된다.
    • 로드 시 위빙(Load-time Weaving):
      • 클래스 로더가 클래스 바이트코드를 JVM에 로드하는 시점에 어드바이스를 삽입.
      • Spring AOP는 기본적으로 로드 시 위빙을 지원하지 않으며, AspectJ를 통합해야 사용 가능합니다.
      • javaagent 옵션을 사용해 위빙을 수행.

        javaagent 옵션이 뭐지? (gpt)

        javaagent는 Java 애플리케이션의 실행 시 JVM에 전달되는 옵션으로, 클래스 로딩 시점에 바이트코드를 조작할 수 있게 해주는 기능입니다. 주요 특징은 다음과 같습니다:

        • 클래스 로딩 시 바이트코드 변경: 클래스가 JVM에 로드될 때 해당 클래스의 바이트코드를 동적으로 수정할 수 있습니다.
        • 비침투적인 코드 변경: 원본 소스 코드를 수정하지 않고도 애플리케이션의 동작을 변경할 수 있습니다.
        • AOP 구현에 활용: 로드 시 위빙을 구현하는 데 사용되어, 횡단 관심사를 효과적으로 분리할 수 있습니다.
    • 런타임 위빙(Runtime Weaving):
      • 런타임 시 프록시 패턴을 사용해 동적으로 어드바이스를 삽입.
      • Spring AOP는 AspectJ의 런타임 위빙 방식을 사용하며, 실제로는 프록시 객체를 생성해 어드바이스를 적용.

트랜잭션 지원

DB를 사용할때 가장 신경써야할 경우는 트랜잭션 처리이다. 스프링에서는 이런 트랜잭션의 관리를 어노테이션이나 XML로 설정할 수 있기 때문에 개발자가 매번 상황에 맞는 코드를 작성할 필요가 없도록 설정되어있다.

스프링의 Bean 생명주기

AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(); 
	ac.register();//빈 추가로 등록
	ac.referesh();//등록하기 위한 갱신
	ac.close();//소멸 메서드, 이때 빈도 같이 소멸

스프링의 Bean 생명주기는 크게 4단계로 나눌 수 있다: 빈 생성, 의존관계 주입, 초기화, 소멸. 각 단계에서 일어나는 일을 살펴보겠다.

1. 빈 생성

  1. 스프링 컨테이너가 시작되면 먼저 컨텍스트라는 메모리 영역을 만든다. 이것이 Application Context이다.

  2. 스프링은 설정 파일(XML, Java Config, 어노테이션)에서 정의된 Bean들의 정보를 읽어 스프링 컨테이너에 등록한다.

  3. Bean 정의에 따라 객체를 생성한다. 이 때 기본적으로 싱글톤 스코프가 적용되며, 필요에 따라 프로토타입, 요청(Request), 세션(Session) 등의 다른 스코프도 적용될 수 있다.

2. 의존관계 주입 (DI)

  1. 스프링은 설정 정보를 기반으로 객체(Bean) 간의 의존관계를 주입한다.
  2. 생성자 주입, 세터 주입, 필드 주입 등의 방식으로 의존성이 주입된다.

3. 초기화

  1. 의존관계 주입이 완료된 후, Bean 초기화 작업을 수행한다.
  2. @PostConstruct 어노테이션이 붙은 메서드가 호출된다.
  3. InitializingBean 인터페이스의 afterPropertiesSet() 메서드가 호출된다.
  4. Bean 설정에서 지정한 사용자 정의 초기화 메서드가 호출된다.
  5. AOP가 적용되는 경우, 이 시점에서 프록시 객체가 생성된다.

4. 사용

  1. 초기화가 완료된 Bean은 애플리케이션에서 사용 가능한 상태가 된다.
  2. 필요에 따라 getBean() 메서드로 Bean을 요청하거나, 의존성 주입을 통해 다른 Bean에서 사용한다.
  3. 싱글톤 Bean의 경우 애플리케이션 종료 시까지 계속 사용된다.

5. 소멸

  1. 애플리케이션 종료 시, 컨테이너는 Bean의 소멸 과정을 시작한다.
  2. @PreDestroy 어노테이션이 붙은 메서드가 호출된다.
  3. DisposableBean 인터페이스의 destroy() 메서드가 호출된다.
  4. Bean 설정에서 지정한 사용자 정의 소멸 메서드가 호출된다.
  5. 이 과정에서 리소스 해제, 연결 종료 등의 정리 작업이 수행된다.

이러한 생명주기 관리를 통해 스프링은 Bean의 안전한 생성, 초기화, 사용, 그리고 소멸을 보장하며, 개발자는 비즈니스 로직에 집중할 수 있게 된다.

1. 싱글톤 스코프 (Singleton)

  • 기본값(Default Scope): 별도로 설정하지 않으면 Singleton 스코프가 적용된다.
  • 특징:
    • 스프링 컨테이너 내에서 단 하나의 인스턴스만 생성된다.
    • 컨테이너가 초기화될 때 빈이 생성되고, 애플리케이션 종료 시까지 유지된다.
    • 애플리케이션 전체에서 공유되므로 상태를 가지는 필드는 사용에 주의해야 한다.
  • 사용 예:
    • 주로 무상태(Stateless) Bean으로 사용한다.
    • Service, Repository 등 공유 가능한 객체에 적합하다.
  • 설정 방법:
    • XML:
    • 어노테이션: 기본값으로 적용됨 (명시 필요 없음).

2. 프로토타입 스코프 (Prototype)

  • 특징:
    • 요청마다 새로운 객체를 생성한다.
    • 컨테이너가 빈을 생성만 하고 이후의 생명주기는 컨테이너가 관리하지 않는다.
    • 의존성 주입으로 사용된 경우: 주입된 시점에 새로운 인스턴스가 생성된다.
  • 사용 예:
    • 상태를 가지는 객체(예: 사용자별 데이터, 단기 객체) 생성에 적합하다.
    • 동일한 클래스를 필요에 따라 여러 번 생성해야 할 때 사용한다.
  • 설정 방법:
    • XML:
    • 어노테이션: @Scope("prototype")

3. 요청(Request) 스코프

  • 특징:
    • HTTP 요청이 들어올 때마다 새로운 인스턴스를 생성하고, 요청이 종료되면 소멸한다.
    • 웹 애플리케이션에서만 사용 가능하며, Spring MVC 컨텍스트에서 동작한다.
    • 각 요청마다 별도의 빈 인스턴스를 제공한다.
  • 사용 예:
    • 요청마다 다른 데이터를 저장하거나 처리해야 하는 경우.
    • 예: HTTP 세션과 별개로 요청별 사용자 데이터를 저장.
  • 설정 방법:
    • XML:
    • 어노테이션: @Scope("request")

4. 세션(Session) 스코프

  • 특징:
    • HTTP 세션과 생명주기가 동일하다.
    • 세션이 유지되는 동안 같은 빈 인스턴스를 제공한다.
    • 웹 애플리케이션에서만 사용 가능하며, 주로 사용자별 데이터 저장에 활용한다.
  • 사용 예:
    • 로그인한 사용자별 데이터를 유지해야 하는 경우.
    • 예: 인증 정보, 사용자 설정 등.
  • 설정 방법:
    • XML:
    • 어노테이션: @Scope("session")

5. 애플리케이션(Application) 스코프

  • 특징:
    • 서블릿 컨텍스트(ServletContext)와 생명주기가 동일하다.
    • 웹 애플리케이션 전체에서 공유되는 빈 인스턴스를 제공한다.
  • 사용 예:
    • 전역적으로 사용할 데이터를 저장하거나 관리해야 할 때.
    • 예: 애플리케이션 설정 값, 공통 리소스.
  • 설정 방법:
    • XML:
    • 어노테이션: @Scope("application")

6. 웹소켓(WebSocket) 스코프

  • 특징:
    • 웹소켓 세션과 생명주기가 동일하다.
    • 각 웹소켓 연결별로 별도의 빈 인스턴스를 생성한다.
  • 사용 예:
    • 웹소켓 통신에서 사용자별 데이터를 저장하고 관리할 때.
  • 설정 방법:
    • 어노테이션: @Scope("websocket")

정리

스코프 생명주기 사용 예

Singleton 컨테이너 시작부터 종료까지 공통 서비스, Repository 등

Prototype 빈 요청 시마다 새로 생성 상태를 가지는 객체, 비공유 객체

Request HTTP 요청 시작부터 종료까지 요청별 데이터

Session HTTP 세션 시작부터 종료까지 사용자별 데이터

Application 애플리케이션(ServletContext) 시작부터 종료까지 전역 설정, 공통 리소스 관리

WebSocket 웹소켓 세션 시작부터 종료까지 웹소켓 연결별 사용자 데이터

profile
순간은 기록하고 반복은 단순화하자 🚀

0개의 댓글