ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 01 스프링 부트란?
    공부/스프링부트 핵심가이드 2023. 7. 11. 19:56
    728x90

    1.1 스프링 프레임워크

    스프링 프레임워크는 자바기반의 애플리케이션 프레임워크

    엔터프라이즈급 애플리케이션을 개발하기 위한 다양한 기능 제공

    목적에 따라 다양한 프로젝트를 제공하는 데 그 중 하나가 스프링 부트

    스프링 부트의 기반인 스프링 프레임워크를 알아보고 스프링이 제공하는 다양한 프로젝트 중 하나인 스프링 부트의 특징 설명

    스프링의 핵심 가치

    "애플리케이션 개발에 필요한 기반을 제공해서 개발자가 비즈니스 로직 구현에만 집중할 수 있게끔 하는 것"

    1.1.1 제어 역전(IoC)

    사용하려는 객체를 선언하고 해당 객체의 의존성을 생성한 후 객체에서 제공하는 기능 사용

    객체를 생성하고 사용하는 일련의 작업을 개발자가 직접 제어하는 구조

    @RestController
    public class NoDIController{
    
    	private MyService service = new MyServiceImlp();
        
        @GetMapping("/no-di/hello")
        public String getHello(){
        return serviece.getHello();
        }

    위는 일반적인 자바 코드에서의 객체 사용법

     

    하지만 제어 역전(IoC:Inversion of Control)을 특징으로 하는 스프링은 기존 자바 개발 방식과 다르게 동작

     IoC를 적용한 환경에서는 사용할 객체를 직접 생성하지 않고 객체의 생명주기 관리를 외부에 위임

    '외부'란 스프링 컨테이너 또는 IoC컨테이너를 의미

    객체의 관리를 컨테이너에 맡겨 제어권이 넘어간 것을 제어 역전이라고 부르며, 제어 역전을 통해 의존성 주입(DI:Dependency Injection), 관점 지향 프로그래밍(AOP:Aspect-Oriented Programming)등이 가능

    스프링을 사용하면 객체의 제어권을 컨테이너로 넘기기 때문에 개발자는 비즈니스 로직을 작성하는 데 더 집중 가능

    1.1.2 의존성 주입(DI)

    의존성 주입(DI:Dependency Injection)이란 제어 역전의 방법 중 하나로, 사용할 객체를 직접 생성하지 않고 외부 컨테이너가 생성한 객체를 주입받아 사용하는 방식

    스프링에서 의존성을 주입받는 방법은 세가지가 존재

    • 생성자를 통한 의존성 주입
    • 필드 객체 선언을 통한 의존성 주입
    • setter 메서드를 통한 의존성 주입

    스프링에서는 @Autowired라는 어노테이션을 통해 의존성을 주입할 수 있음

    • 생성자를 통한 의존성 주입
    @RestController
    public class DIController{
    
    	MyService myService;
        
        @Autowired
        public DIController(MyService myService){
        	this.myService=myService;
        }
        
        @GetMapping("/di/hello")
        public String getHello(){
        	return myService.getHello();
        }
    }
    • 필드 객체 선언을 통한 의존성 주입
    @RestController
    poublic class FieldInjectionController{
    
    	@Autowired
        private MyService myService;
        
    }
    • setter 메서드를 통한 의존성 주입
    @RestController
    public class SetterInjectionController {
    
    	MyService myService;
        
        @Autosired
        public void setMyService(MyService myService) {
        	this.myService = myService;
        }
    }

    공식 문서에서는 의존성 주입방법을 추천한다

    다른 방식과는 다르게 생성자를 통해 의존성을 주입받는 방식은 레퍼런스 객체없이는 객체를 초기화할수 없게 설계할 수 있기 때문

    1.1.3 관점 지향 프로그래밍(AOP)

    관점 지향 프로그래밍(Asoect-Oriented Programming)은 스프링의 아주 중요한 특징

    더보기

    객체지향 프로그래밍(OOP:Object-Oriented Programming)

    • 추상화(abstraction)
    • 캡슐화(encapsulation)
    • 상속(inheritance)
    • 다형성(polymorphism)

    AOP는 관점을 기준으로 묶어 개발하는 방식

    관점(aspect)란 어떤 기능을 구현할 때 그 기능을 '핵심 기능'과 '부가 기능'으로 구분해 각각을 하나의 관점으로 보는 것을 의미

     

    '핵심 기능'은 비즈니스 로직을 구현하는 과정에서 비즈니스 로직이 처리하려는 목적 기능

    ex)클라이언트로부터 상품 정보 등록 요청을 받아 DB에 저장하고 상품 정보를 조회하는 비즈니스 로직을 구현한다면,

    (1)상품정보를 DB에 저장하고, (2)저장된 상품 정보 데이터를 보여주는 코드가 핵심 기능

     

    핵심기능인 비즈니스 로직 사이에 로깅 처리를 하거나 트랜잭션을 처리하는 코드를 예로 들 수 있음

    객체마다 핵심 기능을 수행하기 위한 로직과 함께 부가 기능인 로깅, 트랜잭션 등의 코드를 작성

    상품정보 등록 기능과 상품정보 조회 기능은 엄연히 다른 기능으로 각자 로직이 구현되어 있음

    하지만 유지보수 목적이나 DB접근을 위해 작성된 로깅과 트랜잭션 영역은 상품정보를 등록할 때나 상품정보를 조회할 때 동일한 기능을 수행할 확률이 높음

    즉, 핵심 기능을 구현한 두 로직에 동일한 코드가 포함된다는 것을 의미

    AOP의 관점에서는 부가 기능은  핵심 기능이 어떤 기능인지에 무관하게 로직이 수행되기 전/후에 수행되기만 하면 됨

    이처럼 여러 비즈니스 로직에서 반복되는 부가 기능을 하나의 공통 로직으로 처리하도록 모듈화해 삽입하는 방식을 AOP라고 함

     

    AOP를 구현하는 방법은 세가지

    • 컴파일 과정에서 삽입하는 방식
    • 바이트코드를 메모리에 로드하는 과정에 삽입하는 방식
    • 프락시 패턴을 이용한 방식

    스프링은 디자인 패턴 중 하나인 프락시 패턴을 통해 AOP기능을 제공하고 있음

    스프링 AOP의 목적은 OOP와 마찬가지로 모듈화해서 재사용 가능한 구성을 만드는 것이고, 모듈화된 객체를 편하게 적용할 수 있게 함으로써 개발자가 비즈니스 로직을 구현하는 데만 집중할 수 있게 도와주는 것

    1.1.4 스프링 프레임워크의 다양한 모듈

    스프링 공식 문서에서 제공하는 다이어그램

    스프링 프레임워크는 기능별로 구분된 약 20여 개의 모듈로 구성되어 있음

    스프링 프레임워크 공식 문서에서는 스프링 버전별로 다른 다이어그램을 제시하고 있지만 큰 틀은 유사

    스프링 프레임워크를 사용한다고 해서 모든 모듈을 사용할 필요는 없음

    애플리케이션 개발에 필요한 모듈만 선택해서 사용하게끔 설계되어 있으며 이를 경량 컨테이너 설계라고 부름

    1.2 스프링 프레임워크 vs 스프링 부트

    스프링 프레임워크는 기존 개발 방식의 문제와 한계를 극복하기 위해 다양한 기능을 제공

    하지만 기능이 많은 만큼 설정이 복잡한 편

    필요한 모듈들을 추가하다 보면 설정이 복잡해지는 문제를 해결하기 위해 등장한 것이 스프링 부트

    스프링 부트 공식 사이트에는 다음과 같은 문구가 쓰여 있음

    "스프링 부트를 이용하면 단독으로 실행 가능한 상용 수준의 스프링 기반 애플리케이션을 손쉽게 만들 수 있습니다"

    즉, 별도의 복잡한 설정을 하지 않아도 스프링 부트를 사용하면 개발이 쉬워진다는 것

    스프링 프레임워크와 비교했을 때 스프링 부트가 가진 특징을 아래서 살펴보겠음

    1.2.1 의존성 관리

    스프링 프레임워크에서는 개발에 필요한 각 모듈의 의존성을 직접 설정해야했음

    또한 호환되는 버전을 명시해야 정상 동작

    애플리케이션에서 사용하는 스프링 프레임워크나 라이브러리 버전을 올리는 상황에서는 연관된 다른 라이브러리 버전까지도 고려해야함

     

    스프링부트에서는 이같은 불편함을 해소하기 위해 'spring-boot-starter'라는 의존성을 제공

    spring-boot-starter의 의존성은 여러 종류가 있고 각 라이브러기능과 관련해서 자주 사용되고 서로 호환되는 버전의 모듈 조합을 제공

    이를 통해 개발자는 라이브러리 호환 문제를 해결가능!

     

    많이 사용되는 spring-boot-starter 라이브러리 간략 소개

    • spring-boot-starter-web:스프링MVC를 사용하는 RESTfule애플리케이션을 만들기 위한 의존성, 기본적으로 내장 톰캣이 포함되어 있어 jar형식으로 실행 가능
    • spring-boot-starter-test:JUnit Jupiter, Mockito 등의 테스트용 라이브러리 포함
    • spring-boot-starter-jdbc:HikariCP커넥션 풀을 활용한 JDBC 기능을 제공
    • spring-boot-starter-security:스프링 시큐리티(인증, 권한, 인가 등)기능을 제공
    • spring-boot-starter-data-jpa:하이버네이트를 활용한 JPA기능을 제공
    • spring-boot-starter-cache:스프링 프레임워크의 캐시 기능을 지원
    더보기

    'spring-boot-starter'의 여러 라이브러리를 함께 사용할 때는 의존성이 겹칠 수 있음

    이로 인해 버전 충돌이 발생할 수 있는데, 의존성 조합 충돌 문제가 없도록 'spring-boot-starter-parent'가 검증된 조합 제공

    1.2.2. 자동 설정

    스프링부트는 스프링 프레임워크의 기능을 사용하기 위한 자동 설정(Auto Configuration)을 지원함

    자동 설정은 애플리케이션에 추가된 라이브러리를 실행하는데 필요한 환경 설정을 알아서 찾아줌

    즉, 애플리케이션을 개발하는 데 필요한 의존성을 추가하면 프레임워크가 이를 자동으로 관리

    @SpringBootApplication
    public class SpringBootApplication {
    
    	public static void main(String[] args) {
        	SpringApplication.run(SpringBootApplication.class, args);
        }
    }

    @SpringBootApplication 어노테이션을 주목

    이 어노테이션은 여러 어노테이션을 합쳐 놓은 인터페이스지만 기능 위주로 보면 크게 다음 세 개의 어노테이션을 합쳐놓은 구성

    • @SpringBootConfiguration
    • @EnableAutoConfiguration
    • @ComponentScan

    스프링부트 애플리케이션이 실행되면 우선 @CoimponentScan 어노테이션이 @Component시리즈 어노테이션이 붙은 클래스를 발견해 빈(bean)을 등록함

    이후 @EnableAutoConfiguration 어노테이션을 통해 'spring-boot-autoconfigure'패키지안에 spring.factories 파일을 추가해 다양한 자동설정이 일부 조건을 거쳐 적용됨

    spring.factories파일을 열면  Auto Configure항목이 존재

    org.springframework.boot.autoconfigure.EnableAutoConfiguration하단에 많은 자동 설정이 정의 되어있음

    이 설정은 각 파일에 설정된 @Conditional의 조건을 충족할 경우 빈에 등록되고 애플리케이션에 자동 반영

    더보기

    @Component 시리즈 어노테이션에서 '시리즈'는 @Component 어노테이션이 포괄하는 어노테이션들을 통칭하기 위해 사용한 표현

    @Component 시리즈 어노테이션의 대표적인 예는 아래와 같음

    • @Controller
    • @RestController
    • @Service
    • @Registry
    • @Configuration

    1.2.3 내장 WAS

    스프링부트의 각 웹 어플리케이션에는 내장 WAS(Web Application Server)가 존재

    웹 어플리케이션을 개발할 때 가장 기본이 되는 의존성인 'spring-boot-starter-web'의 경우 톰캣을 내장

    스프링 부트의 자동 설정 기능은 톰캣에도 적용되므로 특별한 설정없이도 톰캣을 실행할 수 있음

    필요에 따라서는 톰캣이 아닌 다른 웹서버(Jetty, Undertow등)로 대체가능

    1.2.4 모니터링

    개발이 끝나고 서비스 를 운영하는 시기에는 해당 시스템이 사용하는 스레드, 메모리, 세션 등의 주요 요소들을 모니터링해야함

    스프링부트에는 스프링부트 액추에이터라는 자체 모니터링 도구가 있음

     

    댓글

Designed by Tistory.