자원 서빙을 위한 핵심 언어, Java

AngJ·2026년 1월 31일
post-thumbnail

서비스를 개발한다면 어떤 플로우로 짜야할까?

프록시 서버: 사용자의 요청을 받음 (진입점) → “내부와 외부를 구분”
NAT: 백엔드에서 처리한 응답을 사용자에게 return 해주는 서버
프론트엔드: 사용자와 가까운 쪽 (Vue.js)
백엔드: 자원이 있는 쪽 (Spring boot)

  • 자원(Resource): 서비스를 이용하기 위한 정보 처리 및 사용자 정보 등

Java는 자원을 다루는 백엔드 개발을 위한 Spring Boot의 초석이 되는 핵심 언어입니다. 특히 대규모 트래픽과 복잡한 비즈니스 로직을 처리해야 하는 엔터프라이즈 환경에서, Java는 엄격한 예외 처리, 객체지향 설계 등 견고한 기능을 통해 시스템의 높은 안정성과 유지보수성을 보장해 줍니다.

Java : “역할을 가진 객체들을 조합하는 언어”
1. Java 프로그램은 클래스 단위로 구성
2. 클래스는 객체로 만들어서 사용
3. Main은 프로그램의 시작점
4. 패키지는 클래스의 논리적 위치
- 패키지: 클래스의 논리적 묶음
5. Import로 다른 클래스를 연결
6. 디렉토리 구조가 중요

클래스
앞선 Java 설명에 대한 내용을 보면 클래스에 대한 여러 언급이 있고, Java 프로그램 작성 시 class를 먼저 선언하고 시작합니다.

클래스의 개념이 탄생하기 전에는 서비스를 개발하기 위해 기존 방식대로 구조를 기능과 데이터로 나누어 개발을 진행 한 후, 구현하려 했으나 정상적으로 서비스가 요구사항 제대로 구현되지 않았습니다.

따라서 클래스의 개념이 탄생하게 되었고, java는 클래스 기반 언어이기에 class를 먼저 선언 후 내용을 작성해 나갑니다.

객체
작성한 클래스를 활용할 때 아래와 같이 ‘Animal a1 = new Dog();’와 같이 객체를 생성하게 됩니다.

클래스를 이용해 객체를 생성할 때, 무작정 객체를 생성하게 되면 많은 객체를 생성하게 되고 결국 객체들이 많은 메모리를 차지해 메모리 오버플로우가 발생합니다. 따라서 객체를 생성하는 방식에 대한 고민을 하게되었고, 이에 객체 생성 패턴이 필요하게 되었습니다.
객체 생성 패턴에는 싱글톤, 팩토리, 빌더 패턴이 있습니다.

1️⃣ 싱글톤 (Singleton)
싱글톤 방식은 객체 생성을 1번만 하고 외부에서 new 연산자로 객체를 생성할 수 없도록 생성자를 private으로 만듭니다. 프로그램 내에 단 하나의 인스턴스만 존재해야할 때 사용하는 것이 좋습니다.

2️⃣ 팩토리 (Factory)
팩토리 방식은 객체 생성 로직을 한 곳에 모아서 관리하는 패턴입니다. New를 통해 객체 생성을 여러 곳에서 하지 않고, “무엇을 만들지”를 공장에 맡기는 방식으로 구현합니다. 따라서 객체 생성 책임을 분리하여 코드 결합도를 낮추고, 변경에 강하게 만들 수 있습니다.

이 패턴은 객체 생성 로직을 클라이언트 코드(사용하는 쪽)로부터 숨기고 싶거나, 조건(if/else)에 따라 생성해야 할 객체의 클래스가 달라질 때, 나중에 새로운 타입의 객체가 추가되어도 기존 코드를 수정하고 싶지 않을 경우 사용하면 좋습니다.

3️⃣ 빌더 (Builder)
빌더 패턴은 필드가 많거나 선택적 값이 많은 객체를 안전하게 생성하기 위한 패턴입니다.

만약 생성자 패턴으로 객체를 생성하게 된다면 순서가 틀려도 컴파일 에러가 발생하지 않는 운영 중 발견되는 최악의 버그가 발생할 수 있습니다. 이를 빌더 패턴을 통해 이름으로 값을 지정하게 된다면 이 문제를 해결할 수 있습니다.

이 패턴은 생성자 인자가 너무 많거나 필수 인자, 선택 인자가 섞여 있을 경우 등에 사용한다면 이점을 발휘할 수 있습니다.

  • 빌더 패턴을 사용한 객체 생성!

최종적으로 위 생성 패턴들을 이용했을 때, 불필요한 메모리 소모를 감소할 수 있습니다.

  • 참고
  1. ‘코드 중복, 의존성 증가, 테스트 어려움’의 문제를 객체 생성 패턴으로 해결할 수 있습니다.
  2. 생성한 객체 중 일부는 아래와 같이 객체를 닫아줘야 합니다.

상속 / 다형성
객체 지향 프로그래밍에서 객체를 효율적으로 활용하기 위해 상속과 다형성을 사용합니다. 이 둘은 밀접하게 연관되어 있습니다.

먼저 상속(Inheritance)은 구조적인 재사용을 담당합니다. 부모 클래스에 공통 기능을 정의하고, 이를 상속받은 자식 클래스에서 차이점만 구현함으로써 코드 중복을 줄이고 계층 구조를 만듭니다.

다형성(Polymorphism)은 이 구조 위에서 동작하는 유연한 활용 기술입니다. 상속받은 여러 자식 객체들을 부모 타입 하나로 묶어서 관리하되, 실제 실행 시점(Runtime)에는 각 자식 객체에 맞는 고유한 동작(메서드)이 동적으로 실행되도록 합니다.

빌드(Build) / 디렉토리 구조
앞선 서비스 플로우를 참고했을 때, DB와 자원 처리를 담당하는 Spring이 연결되어 있습니다. DB를 서비스에 연결하기 위해선Java의 jdbc 를 build를 해야합니다.

빌드란 Java 소스코드로부터 실행 가능한 프로그램으로 변환하는 것을 말합니다. 이때 사용하는 도구로 Gradle과 Maven이 있지만 Gradle을 사용하는 것을 권고하고 있습니다. Maven은 언어를 XML을 사용하는데 해당 언어는 의존성이 복잡하기에 Groovy/Kotlin을 기반으로 하는 Gradle을 사용합니다.

Build를 할 때 ‘./gradlew build’ 명령을 사용하게 되는데, 이 때, build.gradle파일이 위치한 곳에서 위의 명령을 입력해야 합니다. 따라서 디렉토리 구조가 중요합니다.

이제까지 배운 내용을 바탕으로 백엔드 로직을 java를 활용해 간단한 로그인 인증 서비스를 구현해보았습니다. 사용자 인증 정보를 저장할 DB는 MariaDB를 Docker에서 컨테이너로 구동, 사용자 요청 처리를 담당하는 Backend는 pure java, 사용자 입력을 받는 Frontend는 html, css, js를 이용해 Python 명령을 이용해 구동했습니다.

인증을 위해 세션 및 토큰을 더욱 간단한 방법인 spring boot가 아닌 pure 자바를 사용하는 이유는 spring boot는 인증 기능 외에도 프레임워크 차원에서 제공하는 수많은 라이브러리를 함께 로드해야 합니다. 따라서 이러한 무거운 로딩 과정으로 인해 초기 구동 및 요청 처리 시 시간 지연(Latency)이 발생합니다.

Pure 자바를 이용하게 되면 불필요한 외부 라이브러리 없이 필수적인 인증 로직만을 구현할 수 있습니다. 가벼운 구조를 통해 인증 및 인가(Authentication & Authorization) 서비스를 더욱 신속하게 처리하여 전체적인 소요 시간을 단축할 수 있습니다.

profile
항상 왜?를 생각하는 개발자

0개의 댓글