[Spring] Spring Framework (DI/AOP)

Spring의 특징과 장점

  • 애플리케이션 프레임워크
  • 스프링은 Struts같은 웹 애플리케이션 개발용 웹프레임워크와는 달리 어떤 애플리케이션에도 적용가능
  • JEE대체하는 프레임워크
  • 경량컨테이너 <-> EJB  
    • 복잡한 절차를 요구하는 ‘EJB(Enterprise Java Beans’)에 비해 경랑 컨테이너
    • 자바객체를 담고 있고, 자바객체의 생성, 소멸과 같은 라이프 사이클 관리하며 필요한 객체를 가져와 사용 하면서 EJB기능 다수행하면서도 경량  - EJB에 대항하는 것이 바로 Spring
  • 객체를 담고있는 컨테이너를 제공: 컨테이너에 객체를 담아두고 필요할때에 컨테이너로부터 객체를 가져와서 사용
  • 트랜잭션 처리를 위한 일관된 방법을 제공 : 설정 파일을 통해 트랜잭션 관련 정보를 입력하기 때문에, 트랜잭션 구현에 상관없이 동일 한 코드를 여려 환경에서 사용할 수 있음
  • 영속성과 관련된 다양한 API지원 (영속성;DB의 특징, 즉 DB를 가져다 쓰기 위한 API 지원) : JDBC를 비롯한 myBATIS, 하이버네이트, JPA등 데이터베이스 처리를 위해 널리 사용되는 라이브러리 연동을 지원
  • 다양한 API 연동 지원 (DB뿐 아니라 보안 메일등의 API) : JMS,메일, 스케줄링 등 다양한 API를 설정파일과 어노테이션을 통해서 손쉽게 사용 가능 
  • 독립적이고 테스트 가능한 컴포넌트들 작성가능
  • POJO (Plain Old Java Objects) 작성한 후 애플리케이션 컨텍스트라는 핵심 컴포넌트를 통한 의존성 주입 (dependency injection)을 이용해 POJO를 연결
  • 핵심: DI, AOP 

DI (Dependency Injection) / IoC (Inversion of control)

DI란?

  • IoC(Inversion of Control)이라고도 함 (제어의 역전)
    • DI패턴을 지원해주는 프레임 워크(spring) 설정파일과 어노테이션을 이용하여 손쉽게 객체간의 의존 관계 설정 가능  
  • 서비스 구현 클래스내 의존 객체를 직접 생성하지 않고, 생성자에서 의존하는 객체를 전달 받음
    • spring container(스프링내부에 있는 객체(Bean)들간의 관계를 관리)가 필요한 객체를 스스로 끌어들임(밖->안 setMethod 집어 넣음)
    • 외부 라이브러리 같은 의존 관계를 코드 내부에 기술하는 것이 아니라 외부 파일을 이용해서 설정하는 방식 
    • 객체는 의존하고 있는 객체를 직접 생성하거나 검색할 필요 없음
    • 불필요한 의존관계를 없애거나 줄일 수 있음
  • 테스트 수행 수월 (단위 테스트 진행)
  • 의존성 : 어떤 클래스가 자신의 임무를 다하기 위해 필요한 값이나 사용할 다른 클래스와의 관계
  • 주입 : 어떤 클래스의 인스턴스에 대해 외부로부터 ‘의존성’을 설정하는 것.
  • 의존관계 주입 컨테이너의 역할 : 
    • 어떤 클래스가 필요로 하는 값이나 인스턴스를 생성, 취득 그 클래스의 인스턴스에 대해 설정
    • 필요한 인스턴스를 생성, 취득하는 코드를 직접 만들지 않아도 됨
    • 클래스간 관계가 느슨한 결합이 되어 의존성은 약해짐 
  • 내프로그램을 바꾸지 않으면서 쉽게 내가 하는 작업을 바꿀 수 있는 작업

의존관계 주입 방법

생성자 주입

  • 생성자를 통해서 의존 관계를 주입 받는 방법
  • 생성자가 1개만 있으면 @Autowired를 생략해도 자동 주입
  • 불변, 필수 의존관계에 사용
  • 스프링에서 권장하는 방식

수정자 주입

  • setXXX() 형태의 setter라 불리는 필드의 값을 변경하는 수정자 메서드를 통해서 의존관계를 주입하는 방법
  • 선택, 변경 가능성이 있는 의존관계에 사용

필드 주입

  • 필드에 바로 주입하는 방법

일반메서드 주입

  • 일반 메서드를 통해서 주입하는 방법
  • 한번에 여러 필드를 주입 받을 수 있음

어노테이션 기반 자동 설정

  • @Autowired : 의존관계 자동 주입 (스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아서 주입)
  • 생성자에 적용, 설정메소드에 적용, 필드에 적용, 설정파일에 적용 하여 사용
  • import org.springframework.beans.factory annotation.Autowired;

정리

  • 객체 지향 원리 적용
  • DI는 OCP(The Open-Closed Principle)
    A dependency B
    A -----> B
    
  • A의 구조는 바꾸지 못함 (A의 구조는 closed 됨)
  • A 내용은 바꾸게(open, extend) 하고 싶으면 밖에서 수정하여 주입 => DI 

AOP(Aspect-Oriented Programming: 관점지향 프로그래밍)

AOP란?

  • Aspect란 소프트웨어가 갖는 다양한 특징이나 성질
  • 공통관심사항(CCC:Cross Cutting Concern)을 구현한 모듈에 의존 관계를 갖지 않음
    • 공통관심사항 적용으로 인한 의존 관계의 복잡성과 코드 중복을 해소
    • 핵심로직을 핵심관심사항이라고 함 CC(Core Concern)
  • 횡단적 관심사의 분리
    • 일반적으로 하나의 소프트웨어는 복수모듈로 구성
    • 어떤 관심사가 이러한 복수모듈에 산재하는 것을 ‘횡단적’이라고 하는데, 횡단적 관심사의 구체적인 예로 “LOG 출력”
  • an Advanced Separation of Concern 분리된 관심사는 AOP프레임워크에 의해 관리되고, 필요에 따라 필요한 시점에 각 모듈에 삽입
  • 각 모듈에서 분리된 기능을 사용하기 위한 코드를 기술할 필요 없음
    • 모듈 개발자는 횡단적 관심사에 대해 젼혀 관여안함
    • 고도로 분리된 관심사는 객체 지향보다 한층 독립성이 강해지는 것은 물론 재사용성과 보존성이 향상
    • 코드에 손대지 않고도 새로운 기능  추가 가능
  • 트랜잭션이나 로깅, 보안과 같이 여러 모듈에서 공통으로 필요로 하지만 실제 모듈의 핵심은 아닌 기능들을 분리해서 각 모듈에 적용 가능
  • 공통관심사항을 구현한 Aspect 클래스를 작성하고, 설정파일을 이용하여 Aspect를 핵심 로직을 구현한 클래스에 적용

Spring 에서 AOP

  • 객체 지향에 의존 관계 주입과 AOP를 조합함으로써, 보다 유연하고 보존성인 높은 견고한 소프트웨어를 개발 가능
    • 객체지향에서는 기능과 데이터를 하나의 클래스 단위로 묶어 모듈로 부터 분리하여 재사용성과 보존성을 높임
  • 핵심로직을 구현한 클래스를 실행하기 전 후에 Aspect를 적용, spring AOP는 핵심로직 수정하지 않고 적용이 가능 함
    • CC/CCC를 따로 구현하면, Spring 돌면서 실행은 섞여서 돌아가는 것처럼 보이게 됨
  • 순수 Java로 구현
  • 현재 메소드 실행 조인 포인트만 지원

AOP 용어

  • Aspect (관점) : 여러 클래스에 걸쳐있는 관심사의 모듈화
    • Spring AOP에서 aspect는 일반 클래스 (스키마 기반 접근) 또는 주석이 달린 일반 클래스 @Aspect(@AspectJ 스타일)를 사용
  • Advice (어드바이스)
    • 관점으로서 분리되고 실행시 모듈에 위빙된 구체적인 처리
    • 언제 공통관심 기능을 핵심로직에 적용할 지를 정의
    • 메서드를 호출하기전에(언제) 트랙잭션을 시작한다(공통기능) 기능을 적용한다는 것을 정의
    • Around Advice : Joinpoint 앞과 뒤에서 실행되는 Advice
    • Before Advice :  Joinpoint 앞에서 실행되는 Advice
    • After Returning Advice : Joinpoint 메서드 호출이 정상적으로 종료된 뒤 실행되는 Advice
    • After Throwing Advice : 예외가 던져질 때 실행되는 Advice
    • Instroduction : 클래스에 인터페이스와 구현을 추가하는 특수한 Advice
  • Joinpoint (조인포인트)
    • Advice를 위빙하는 포인트(적용 가능한 지점)
    • 특정 이름을 가진 메서드 실행하는 지점
  • Pointcut (포인트컷)
    • 하나또는 복수의 joinpoint를 하나로 묶은 것
    • Jointpoint의 부분 집합으로서 실제로 Advice가 적용되는 Jointpoint나타냄
  • Advisor (어드바이저)
    • Advice와 Pointcut을 하나로 묶어 다루는 것
    • 특정 결합 지점에서 측면에 의해 취해진 조치
  • Weaving (위빙)
    • Advice를 핵심 로직 코드에 적용하는 것
    • 관심사를 다시 모듈에 삽입하는 것
    • Spring AOP는 런타임에 위빙을 수행
  • AOP 프록시 : aspect 계약을 구현하기 위해 AOP 프레임 워크에 의해 생성 된 객체

POJO (Plain Old Java Object) 

  • 보통의 Java의 객체
  • 자바코드를 이용해서 객체를 구성하는 방식을 그대로 스프링에서 사용
  • 특정한 인터페이스를 구현하거나 클래스를 상속받지 않은 객체
  • 기존에 작성한 코드 수정없이 사용 

references

https://docs.spring.io/spring-framework/docs/3.0.x/spring-framework-reference/html/overview.html
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html