imhamburger 님의 블로그

데이터엔지니어 부트캠프 - 스프링부트(Springboot) 이해하기 (15주차) 본문

데이터엔지니어 부트캠프

데이터엔지니어 부트캠프 - 스프링부트(Springboot) 이해하기 (15주차)

imhamburger 2024. 10. 20. 17:50

스프링부트를 알기 전에 스프링부터 알아보자.

 

스프링(Spring)

 

스프링(Spring)은 자바(Java) 기반의 애플리케이션 프레임워크이다.

프레임워크란 말그대로 뼈대를 의미하는데 애플리케이션 프레임워크는 애플리케이션 개발을 빠르고 효율적이게 하기 위한 툴이다.

 

예를 들어, 우리가 웹사이트를 만든다고 하면 로그인 기능이나 데이터베이스 연결 같은 부분을 매번 새로 만들 필요 없이,

스프링이 제공하는 기능을 써서 바로 사용할 수 있다.

로그인은 Spring Security를 사용하고 데이터베이스는 Spring Data JPA를 사용하는데 복잡한 SQL을 작성하지 않고 자바 객체로 데이터베이스와 쉽게 상호작용할 수 있게 도와준다.

 

다시 말하자면,

각 프로젝트에서 개발자는 이러한 스프링 프레임워크를 이용하여 프로그램의 기본흐름이나 구조를 정하고, 개발자들은 이 위에 코드를 추가하는 방식이다. 이미 스프링 프레임워크에선 개발에 필요한 구조를 만들어 놓았기 때문에 개발자는 필요한 부분만 바꾸는 형태로 개발이 가능하다.

 

스프링이 나오기 전에도 비슷한 기능을 제공하는 자바 EE 라는 것이 존재하였는데 문제가 많았다고 한다. 따라서 스프링을 개발한 사람은 '추운 겨울이 지나고 봄이왔다.' 라는 의미로 '스프링'이라는 이름으로 지었다고 하는데 맞나?

 

그럼 스프링부트(Springboot)는 뭐야?

 

 

스프링부트(Springboot)

 

스프링 프레임워크를 더 쉽게 사용할 수 있도록 도와주는 확장 도구라고 생각하면 된다.

 

Spring에서는 개발자가 직접 설정 파일을 작성하여 스프링 컨테이너를 구성하고, 필요한 객체를 등록하고, 객체 간의 의존성을 설정해야 한다.

따라서 스프링은 복잡한 설정을 하나하나 손으로 해줘야 했는데,

스프링부트는 이런 설정을 자동으로 처리해줘서 빠르게 애플리케이션을 개발할 수 있다. 그래서 'boot'라는 단어가 붙여졌나보다.

스프링부트는 자바(Java) 기반의 애플리케이션 프레임워크으로 엔터프라이즈급 애플리케이션을 개발하기 위한 기능을 제공한다.

 

엔터프라이즈급 애플리케이션을 개발하기 위한 기능??
엔터프라이즈급 애플리케이션은 대규모 기업 환경에서 필요한 복잡하고 중요한 애플리케이션을 개발할 때 사용하는 시스템이다.
여기에는 확장성, 고가용성, 보안, 트랜잭션 관리, 분산 처리 같은 여러 복잡한 기능들이 필요하고, 스프링(Spring)은 이런 기능들을 손쉽게 구현할 수 있도록 다양한 도구와 기능을 제공해준다.

 

 

스프링부트의 주요 기능은 여러가지가 있다.

  • Auto-Configuration: 스프링부트는 필요한 설정을 자동으로 해준다. 예를 들어, 데이터베이스 연결, 웹 서버 설정, 보안 설정 같은 것들을 개발자가 직접 설정하지 않아도 기본적인 설정을 자동으로 처리해줘서 초기 설정 시간을 크게 줄일 수 있다.
  • 독립 실행형 애플리케이션: 애플리케이션이 독립적으로 실행될 수 있다. 즉, 외부에서 별도로 톰캣(Tomcat) 같은 웹 서버를 설치하지 않아도, 애플리케이션 안에 내장된 서버를 사용해서 바로 실행할 수 있다.
  • 간단한 시작: 스프링부트에는 다양한 "스타터" 패키지가 있다. 예를 들어, Spring Boot Starter Web은 웹 애플리케이션을 만들 때 필요한 라이브러리들을 묶어 제공해준다.
  • 개발 도구 제공: 개발 중에 애플리케이션을 수정하면 자동으로 다시 시작되게 해주는 Spring Boot DevTools라는 도구가 있다. 덕분에 코드를 수정할 때마다 매번 애플리케이션을 수동으로 재실행하지 않아도 된다.

결론적으로, 스프링부트는 스프링을 더 쉽게 쓰기 위한 도구로, 개발자들이 번거롭게 설정 파일을 하나하나 작성하지 않아도 간편하게 웹 애플리케이션을 만들고 실행할 수 있도록 도와준다. 빠르게 개발하고 배포하는 데 큰 도움이 된다!!

 

 

근데 더 알아야 할 중요한 특징이 있다.

바로 의존성 주입이다.

 

 

의존성 주입(DI)?

 

의존성 주입(Dependency Injection)은 객체 지향 프로그래밍에서 객체 간의 의존 관계를 외부에서 설정해주는 설계 패턴이다.

이 패턴을 사용하면 객체들이 다른 객체에 직접 의존하지 않고, 외부에서 필요한 객체를 전달(주입)받아 사용할 수 있다.

이를 통해 유연성과 재사용성을 높이고, 테스트나 유지보수를 쉽게 할 수 있다.

 

객체? 클래스? 인스턴스?
객체(Object), 클래스(Class), 그리고 인스턴스(Instance)는 객체지향 프로그래밍(OOP)의 핵심 개념
클래스(Class)는 쉽게 생각하자면 객체의 정보가 담긴 레시피북이라고 생각하면 된다. 그니까 무엇을 만들기 위한 틀, 지침서이다.
객체(Object)는 레시피북을 이용해 만들어진 쿠키이다. 즉, 클래스를 사용해서 만들어진 실제 물건이라고 할 수 있다.
인스턴스(Instance)는 코드에서 쿠키레시피라는 클래스에서 만들어진 쿠키(객체)를 불러와 쓸 때, "이건 쿠키레시피로 만든 쿠키 인스턴스"라고 표현한다.

 

따라서 의존성 주입은 User Class가 있고 Product Class 가 있고, 내가 Product Class에서 User Class에 있는 여러가지 정보 중 유저ID 정보를 빌려다가 쓸 때, "필요한 유저ID 객체를 전달받아 사용했다~" 라고 표현할 수 있다. 여기에서 나는 User Class에 있는 모든 객체를 쓴 것이 아닌 유저ID만 가져다가 쓴 것이다.

 

 

스프링에서 의존성 주입

 

스프링은 IoC(제어의 역전) 컨테이너라는 기능을 통해 객체 생성과 의존성 주입을 관리한다.

개발자는 객체를 직접 생성하거나 의존 관계를 일일이 설정할 필요 없이, 스프링이 알아서 필요한 객체를 주입해준다.

스프링에서 의존성 주입을 하려면, 보통 @Autowired 어노테이션을 사용해 객체를 주입받는다.

 

코드예시

@Service
public class UserService {
    private final UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public User findUserById(Long id) {
        return userRepository.findById(id);
    }
}

 

여기서 스프링은 UserService를 사용할 때 UserRepository 객체를 자동으로 찾아서 주입해준다. 개발자가 객체를 직접 생성하거나 관리하지 않아도, 스프링이 의존성을 관리해주는 것이다.

 

의존성 주입을 왜 사용하지?

  • 결합도 감소: 클래스가 직접 다른 클래스에 의존하지 않아서, 변경 사항이 발생해도 유연하게 대응할 수 있다.
  • 테스트 용이: 외부에서 객체를 주입받기 때문에, 모의 객체(mock object)를 사용해서 테스트할 수 있다.
  • 유지보수성: 코드가 변경되더라도 의존 관계를 쉽게 관리할 수 있어서 유지보수가 쉬워진다.

결론적으로, 의존성 주입은 객체 간의 결합을 줄이고, 코드의 재사용성과 유연성을 높여준다.

스프링 프레임워크는 이 의존성 주입을 매우 쉽게 처리할 수 있도록 도와주는 강력한 도구를 제공하고 있다.

 

 

스프링부트 시작하기

 

1. 스프링부트 initializr에 접속한다.

 

 

2. 본인에게 맞는 옵션들을 선택한다. 나의 경우 Dependencies는 Spring Web, Thymeleaf, Spring Boot DevTools 을 추가하였다.

 

 

3. GENERATE 를 눌러 jar 파일을 받는다.

 

 

4. jar 파일 unzip 하기

unzip <jar 파일명>

 

unzip하면, 스프링부트에서 개발을 위한 여러 폴더가 생성된다.

 

 

5. Gradle을 사용하여 스프링부트 프로젝트를 실행하기

./gradlew bootrun

 

이 명령어는 스프링부트 애플리케이션을 실행하는 역할이다.

이 명령어를 사용하면 애플리케이션을 빠르게 실행해서 실시간으로 코드 변경을 확인하거나 테스트할 수 있다.

 

프로젝트 폴더에서 위 명령어를 터미널에 입력하면,

애플리케이션이 실행되고 로컬 서버가 실행되는데 보통 기본적으로 http://localhost:8080에서 애플리케이션을 확인할 수 있다.

 

처음에는 당연히 404 에러가 뜨는데

src/main/resources/static 폴더 안에 껍데기index.html 생성하면 404 에러가 아닌 빈 화면이 보일 것이다.

 

 

6. 작업이 끝난 프로젝트 빌드하기 (jar 파일 생성)

./gradlew build

 

이 명령어는 프로젝트를 빌드하는 역할이다. 즉, 코드, 의존성, 설정 파일을 모두 묶어서 실행 가능한 JAR 또는 WAR 파일을 생성한다.

 

위 명령어를 입력하면, Gradle이 소스 코드를 컴파일하고, 필요한 의존성들을 설치하며, 프로젝트에 포함된 테스트를 자동으로 실행한다. 테스트가 모두 통과하면 최종적으로 빌드된 파일을 만들어내는데 이 파일은 build/libs/ 폴더에 저장된다.

 

 

7. 프로젝트 실행해보기

java -jar build/libs/<내 프로젝트명>SNAPSHOT.jar

 

 

 

개발 중에는 bootrun으로 애플리케이션을 실행하고, 최종 배포할 때는 build로 패키징한 다음, 서버에 배포하는 과정으로 작업을 진행할 수 있다.

 

 

스프링부트 Controller?

 

스프링부트에서 unzip하면 controller라는 폴더가 생성된다.

 

스프링부트에서 Controller는 사용자의 요청을 처리하고 그에 대한 응답을 반환하는 역할을 하는 핵심적인 구성 요소이다.

웹 애플리케이션에서는 주로 브라우저나 클라이언트가 서버로 보내는 요청을 받고, 필요한 작업을 처리한 후, 결과를 클라이언트에게 응답으로 반환해주는 역할을 한다. 

 

다시말해, Controller는 사용자가 웹 페이지나 API를 통해 서버에 요청을 보내면, 그 요청을 받아서 처리하고, 그 결과를 사용자에게 다시 응답해주는 중간 관리자 역할을 한다.

 

코드예시

@Controller
public class HomeController {

    @GetMapping("/home")
    public String home() {
        return "home";  // "home.html"이라는 뷰 파일을 반환함
    }
}
  • @GetMapping("/home"): 클라이언트가 "/home"이라는 URL로 GET 요청을 보내면, 이 메서드가 실행
  • return "home": home.html 파일을 반환해서 사용자에게 보여준다. (html 파일은 templates 라는 폴더 안에 생성해놓기!!)

 

스프링부트에서 Controller는 보통 @Controller 또는 @RestController 어노테이션을 붙여서 선언된다.

이 어노테이션들은 해당 클래스가 웹 요청을 처리할 준비가 되어 있다는 것을 스프링에게 알려준다.

  • @Controller: 주로 HTML 페이지나 뷰 템플릿(Thymeleaf 등)을 반환할 때 사용
  • @RestController: JSON 또는 XML과 같은 데이터를 반환할 때 주로 사용. 이는 RESTful 웹 서비스를 만들 때 유용

 

 

 

일주일을 보내면서...


이번 주는 자바를 배우며 새로운 도전에 직면한 시간이었다. 아직 파이썬도 완벽하게 익히지 못했는데, 자바는 그보다 더 많은 세부 사항을 신경 써야 해서 쉽지 않았다. 하지만 자바를 짧은 시간 안에 완벽히 마스터하려는 것이 아니라, 코드를 보고 어느 정도 이해할 수 있는 수준을 목표로 하고 있다.

그리고 자바와 함께 스프링부트도 배웠다. 스프링부트는 복잡하게 느껴졌지만, 개발을 더 편리하게 해주는 도구임을 알게 되었고, 모든 것을 능숙하게 다루기보다는 그 개념과 사용하는 이유만 제대로 이해해도 충분할 것 같다는 생각이 들었다.

 


앞으로 나의 방향


다가오는 11월 3일, ADsP 자격증 시험을 준비해야 하는 시기가 다가오고 있다. 알고리즘 공부도 병행하고 있는데, 알고리즘 이론은 어느 정도 이해가 되지만 실제로 구현하는 과정은 여전히 어렵다. 그러나 꾸준히 연습하면 실력이 쌓일 것이라고 믿는다.

ADsP 시험 준비도 틈틈이 해나가면서, 일주일 전에 집중적으로 학습하여 좋은 결과를 얻고 싶다...(가능..?)