Back-end/Spring

[Spring] Spring Framework의 정의와 특징에 대해 알아보자 (Ioc,DI,AOP)

랑 이 2024. 9. 29. 03:28
반응형

Spring Boot (스프링 부트)

스프링 프레임워크 (Spring Framework)는 자바 기반의 애플리케이션 프레임워크입니다 

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

 

엔터프라이즈급 개발

"기업 환경을 대상으로 하는 개발"

 

Spring Boot는 Spring Framework를 기반으로 한 간편하고 신속한 애플리케이션 개발을 위한 도구

 

Spring Framework (스프링 프레임워크)

스프링 프레임워크는 현재 자바에서 가장 많이 사용되는 프레임워크로 알려져 있습니다 

우리나라에서는 "전자 정부 프레임워크"의 기반 기술로 공공기관 웹 서비스를 개발하는데 주로 사용됩니다

 

스프링 프레임워크는 자바로 애플리케이션을 개발하는데 필요한 기능을 제공하고 쉽게 사용할 수 있도록 하는 도구입니다 

 

스프링의 핵심 가치 

"애플리케이션 개발에 필요한 기반을 제공해서 개발자가 비즈니스 로직 구현에 집중"

 

Spring Framewokr 모듈

Spring Framework는 약 20개의 모듈로 이루어진 기능으로 구성됩니다

 

경량 컨테이너 설계

애플리케이션 개발에 필요한 모듈들만 선택하여 사용할 수 있도록 설계되어 있습니다

 

1. Spring Core 

스프링의 핵심 모듈이며 의존성 주입(DI)와 제어 역전(IoC)을 구현하는 기본 컨테이너를 제공

 

2. Spring AOP 

AOP를 사용하여 비즈니스 로직과 분리된 관심사(로깅,트랜잭션 관리)를 구현

 

3. Spring Data

데이터베이스 액세스와 관련된 기능을 추상화 JPA,JDBC,MongoDB,Redis 등 다양한 데이터 저장소를 지원

 

4. Spring MVC

웹 애플리케이션 개발을 위한 Model-View-Controller 패턴을 지원 REST API 개발에 주로 사용 


 

Spring 의 핵심 개념

제어 역전 (Ioc Inversion of Control)

객체의 생명 주기와 의존성 관리를 개발자가 아닌 스프링 컨테이너가 책임지도록 하는 디자인 패턴

객체의 관리를 컨테이너에 맡겨 제어권이 넘어간 상태를 의미합니다

 

사용할 객체를 직접 생성하지 않고 생명주기 관리를 외부에 위임하여 제어 역전을 통해

의존성 주입(DI)과 관점 지향 프로그래밍(AOP)을 구현 가능하게 합니다 

 

'외부'는 스프링 컨테이너(Spring Container) 또는 IoC 컨테이너(Ioc Container)를 의미합니다

 

일반적인 자바에서는 객체를 사용하기 위해서 객체를 선언하여 의존성을 생성하여 제공하는 기능을 사용하는 방식으로 객체를 개발자가 직접 관리하고 있습니다 

 

의존성

"파라미터나 리턴값 또는 지역변수 등으로 다른 객체를 참조하는 것"

  • 일반적인 자바 코드의 객체 사용
@RestController 
public class HelloController {

    private HelloService helloService = new HelloService(); // 객체 생성 
   
    @GetMapping("/api/hello")
    public String getHello() {
	  return helloService.getHello();
    }
}

 

의존성 주입(DI Dependency Injection) 

객체 간의 의존성을 애플리케이션 코드가 아닌 프레임워크가 관리하도록 하는 디자인 패턴

제어 역전 방법 중 하나이며 사용할 객체를 직접 생성하지 않고 외부 컨테이너가 생성한 객체를 주입받아 사용합니다

 

@Autowired: 스프링 컨테이너에 있는 빈을 주입시키는 어노테이션입니다 생성자,필드,Setter 3가지 방법에 사용됩니다

 

빈(Bean)

스프링 컨테이너는 빈이 생성되고 소멸까지 생명주기를 관리하며 빈은 스프링 IoC 컨테이너가 생성하고 관리하는 객체입니다

 

빈(Bean)의 특징

스프링 컨테이너가 생성 및 관리하기 때문에 개발자가 객체를 생성하지 않고 스프링 컨테이너가 빈을 생성하고 의존성을 주입하며 하나의 빈 인스턴스만 생성하고 이를 재사용하게 됩니다 빈은 밑에 있는 3가지 방법으로 의존성을 주입합니다 


대표적인 스프링 의존성 주입 방법 3가지 

1. 생성자를 통한 의존성 주입

@RestController 
public class HelloController {
		
HelloService helloService;

    @Autowired 
    public HelloController(HelloService helloService) {
	this.helloService = helloService;
    }

    @GetMapping("/api/hello")
    public String getHello() {
	return helloService.getHello();
    }
}

스프링이 객체를 생성할 때 생성자를 호출하며 의존성을 주입합니다 

참조하는 객체 없이는 객체를 초기화할 수 없기 때문에 항상 초기화된 상태로 생성되어 스프링에서 권장하는 방식입니다

2. Setter 메소드를 통한 의존성 주입

@RestController 
public class SetterHelloController {
		
HelloService helloService;

    @Autowired 
    public void setHelloService(HelloService helloService) {
	this.helloService = helloService;
    }

    @GetMapping("/api/hello")
    public String getHello() {
	return helloService.getHello();
    }
}

Setter 메소드를 구현하여 객체를 인자로 받아 초기화하는 의존성 주입 방법입니다

의존성을 선택적으로 주입할 수 있기 때문에 초기화가 필요 없는 경우에 유연하게 사용될 수 있습니다

3. 필드 객체 선언을 통한 의존성 주입

@RestController 
public class FieldHelloController {
	
    @Autowired 
    private HelloService helloService;
}

객체 선언과 동시에 객체를 초기화하는 방식의 의존성 주입 방법입니다

테스트와 유지보수가 어려워지며 객체 간 결합도가 높아질 수 있기 때문에 권장하지 않는 방식입니다

의존성 주입 비교

방식 장점 단점 권장 여부
생성자 주입 - 객체 불변성 보장
- 테스트 및 유지보수 용이
- 의존성이 많을 경우 생성자가 복잡해질수 있음  권장함
Setter 주입  - 선택적 의존성 주입 가능
- 의존성 변경 용이
- 객체가 초기화되지 않을 가능성이 있음 중간
필드 주입 - 간단한 코드 - 테스트 어려움
- 객체 결함도 높음
권장하지 않음

 

왜 생성자 주입이 항상 초기화된 상태를 보장해야 안전할까?

객체를 생성 할때 스프링 프레임워크는 생성자의 매개변수로 필요한 모든 의존성을 자동으로 주입하기 때문에 객체는 의존성이 주입된 상태로 생성되며 불완전한 상태로 생성될 위험은 없습니다

 

하지만 Setter 주입,필드 주입 방식은 객체가 의존성을 주입받지 못한 상태로 존재할 수 있기 때문에 런타임 시점에서 NullPointException 등 문제가 발생할 수 있기 때문에 초기화된 상태를 보장해야 합니다


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

관점을 기준으로 개발하는 방식을 의미합니다

어떠한 기능을 구현할때 "핵심 기능""부가 기능"으로 구분하여 하나의 관점으로 보는 것

 

핵심기능 

비즈니스 로직을 구현할 때 비즈니스 로직이 처리하려는 목적 기능을 핵심 기능이라고 할 수 있다

 

클라이언트에서 글 등록 요청이 왔을 때 데이터베이스에 저장 후 해당 글을 조회하는 비즈니스 로직을 구현할 때

데이터베이스에 저장과 저장된 글의 내용의 데이터를 보내주는 기능이 핵심 기능이다

 

부가 기능

애플리케이션을 개발할 때 여러 가지 부가기능을 추가할 때가 있는데 크게 비즈니스 로직의 로깅 처리트랜잭션 처리가 부가기능이다

 

관점지향 프로그래밍은 OOP(Object-Oriented Programming)을 효과적으로 사용할 수 있는 개념

 

객체지향 프로그래밍(OOP) 4가지 특징

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

OOP 방식의 애플리케이션 로직

각각의 객체(프레젠테이션,비즈니스 등등)에서 핵심 기능을 수행하기 위한 로직 + 부가 기능 (로깅,트랜잭션)의 코드를 작성

 

비즈니스 로직인 글 등록과 글 조회 기능은 서로 다른 기능으로 다른 로직으로 구현되지만 유지보수 및 데이터베이스 접근을 위해 작성된 로깅과 트랜잭션은 글 등록과 글 조회 기능을 수행할 때 공통적으로 사용될 수 있기 때문에 핵심 기능을 구현한 로직에 공통되는 코드가 작성됩니다

AOP 방식의 애플리케이션 로직

비즈니스 로직에 반복적으로 사용되는 부가 기능을 공통 로직으로 처리할 수 있도록 모듈화 하여 삽입하는 방식을 AOP라고 합니다

AOP 구현 방법으로는 크게 컴파일 과정에 삽입,바이트코드를 메모리에 로드 중에 삽입,프락시 패턴 사용이 있습니다 

 

스프링은 프락시 패턴으로 AOP를 구현할 수 있는 기능을 제공합니다

AOP의 목적으로는 모듈화 하여 재사용 구성을 만들어 편리하게 사용할 수 있도록 만들어 개발자가 비즈니스 로직에 집중할 수 있도록 하는데 이점을 두고 있습니다 

 

고자료

https://wikibook.co.kr/springboot/

https://goldenrabbit.co.kr/product/springboot3java/

반응형