。゚(*´□`)゚。

코딩의 즐거움과 도전, 그리고 일상의 소소한 순간들이 어우러진 블로그

프로젝트/BleuAuction

[BleuAuction 리팩토링] 12/18 (월) 어디까지 하셨어요

quarrrter 2023. 12. 18. 19:27

오늘도 돌아온 월요일 

5인이 모두 출석했다. 

시작은 성주님 지원 몇 군데 하셨어요 ? 

 

우리 희망 종1님이 취직을 해서 떠난다. 우린 아직 그를 떠나보낼 준비가 안 되었는데 ,,,, 

저녁에 하면 볼 수 있을지도 모른다는 여지를 남겨 우린 그 말에 매달려본다 .... 

 

아무튼 백 팀은 계속 서비스 나누기 작업을 계속 하고 있다. 

종원님은 맡은 부분을 다 했다고 했고 나도 이제 기능 두 개 기현오빠는 세 개 남았다고 했다. 

목요일까지 모두 분리해오기로 했다. 

 

종1님이 작업하다가 내가 커밋했던 부분을 날려서 다시 복원을 했었는데 테스트는 안 해놔서 깃에 가서 다시 긁어왔다. 기록이 모두 남는 깃의 대단함(?) 소중함(?)을 다시 한 번 느꼈다. 이전에 내가 뭘 어떻게 했는지 알 수 있는게 정말 좋은 것 같다. 옛날 무역회사 다닐 땐 한 번 저장하면 끝이었고 돌아갈 수 없었어서 난 깃이 더더 대단하게 느껴진다. 

 

백 리뷰를 마치고 프론트로 넘어갔는데 또 캐시파일이 문제였다. 성주오빠는 끝까지 고통 받는다. 하지만 설정 다시 했고 다 날리고 새로 받으면 괜찮지 않을까 ,, 성주오빠 깃 푸시를 40분 가량 함께 했다. 끝내 해결 못 하구 그냥 날리기로 했다. 약간 허망했다. 흑흑 

커밋을 언제 했는지 다 보여서 같이 보면서 성주오빠는 또 잔소리를 들었다. 매의 눈 방선생과 종원느님. 

 

소문자 파일 밑에 대문자 파일이 새로 만들어져 있었다 ;

 


springframe 동작원리

Spring Framework는 자바 기반의 오픈 소스 프레임워크로서, 엔터프라이즈급 애플리케이션을 개발하기 위한 다양한 모듈과 기능을 제공합니다. Spring의 핵심적인 동작 원리는 IoC (Inversion of Control)와 DI (Dependency Injection), AOP (Aspect-Oriented Programming)에 기반하고 있습니다. 아래에서는 Spring Framework의 주요 동작 원리를 간략하게 설명합니다.

1. IoC (Inversion of Control):
제어의 역전 (Inversion of Control): IoC는 객체의 생성 및 생명주기 관리를 개발자가 아닌 프레임워크가 담당하는 것을 의미합니다. 개발자는 객체를 직접 생성하지 않고, 프레임워크에 의해 관리되는 컨테이너에 의해 객체가 생성되고 주입됩니다.

컨테이너 (Container): Spring IoC 컨테이너는 ApplicationContext라고도 불리며, 객체의 생성, 관리, 주입, 생명주기를 담당합니다. 이를 통해 개발자는 애플리케이션의 핵심 로직에 집중할 수 있습니다.

2. DI (Dependency Injection):
의존성 주입 (Dependency Injection): DI는 객체 간의 의존성을 컨테이너가 관리하고, 이를 주입해주는 것을 말합니다. 객체는 직접 의존하는 객체를 생성하지 않고, 컨테이너에게 주입받아 사용합니다.

의존성 주입 방법:
Constructor Injection: 생성자를 통해 의존성을 주입합니다.
Setter Injection: Setter 메서드를 통해 의존성을 주입합니다.
Method Injection: 일반 메서드를 통해 의존성을 주입합니다.

 


3. AOP (Aspect-Oriented Programming):
관점 지향 프로그래밍 (Aspect-Oriented Programming): AOP는 횡단 관심사(로깅, 트랜잭션, 보안 등)를 모듈화하고 재사용 가능한 측면(Aspect)으로 만들어 코드의 중복성을 줄이고 모듈성을 향상시킵니다.

AOP 용어:
Aspect: 횡단 관심사를 정의한 모듈.
Advice: 횡단 관심사에 대한 구체적인 구현. (Before, After, Around 등)
Join Point: Advice가 실행될 수 있는 지점. 메서드 호출, 필드 값 변경 등이 될 수 있음.
Pointcut: 어떤 Join Point에서 Advice를 실행할지를 정의.
4. Spring MVC:
Model-View-Controller (MVC): Spring MVC는 웹 애플리케이션을 개발하기 위한 모델-뷰-컨트롤러 아키텍처를 제공합니다. 클라이언트의 요청은 컨트롤러가 처리하고, 비즈니스 로직은 서비스에서 수행하며, 결과는 뷰에 전달하여 사용자에게 제공합니다.

DispatcherServlet: Spring MVC의 핵심 컨트롤러로서 클라이언트의 모든 요청을 중앙에서 관리하고, 요청에 따라 적절한 핸들러(컨트롤러)에게 전달합니다.

Handler Mapping: 클라이언트의 요청 URL을 실제 처리할 컨트롤러와 매핑합니다.

View Resolver: 뷰의 논리적인 이름을 실제 뷰 템플릿과 매핑하여 결과를 생성합니다.

이러한 원리들은 Spring Framework가 유연하고 모듈화된 방식으로 개발을 가능하게 하며, 코드의 재사용성과 유지보수성을 향상시킵니다. Spring은 또한 다양한 모듈을 지원하여 데이터 액세스, 트랜잭션 관리, 보안, 메시징 등 다양한 영역에서 활용할 수 있도록 합니다.

 

전자정부프레임워크란

등장배경 및 목적
개발프레임워크는 정보시스템 개발을 위해 필요한 기능 및 아키텍처를 미리 만들어 제공함으로써 효율적인 어플리케이션 구축을 지원합니다.
“전자정부 표준프레임워크”는 공공사업에 적용되는 개발프레임워크의 표준 정립으로 응용 SW 표준화, 품질 및 재 사용성 향상을 목표로 합니다.

 

전자정부프레임워크란 행정안전부 산하 한국정보화진흥원에서 만든 웹 기반 어플리케이션 프레임워크로서 정부 및 공공기관, 공기업 등의 웹사이트에 자주 쓰이는 공통 기능들을 Java의 Spring 프레임워크와 유명 Java 라이브러리(iBatis/MyBatis, Jackson, Apache Commons 등)를 가지고 미리 만들어 놓은 공통컴포넌트와 이를 개발하는 개발환경, 실행환경, 운영환경, 관리환경 등으로 구성되어있다.

전자정부 프레임워크는 아시다시피 Spring + 기타 플러그인(컴포넌트)를 하나로 묶어 패키지화 한 것 입니다.

 

자정부표준프레임워크, 약칭 eGov는 공공기관 웹사이트 개발 과정을 표준화하기 위한 의도에서 시작되었으나, 그러한 의도로 인해 구조가 경직되고 최신 기술을 반영하지 못하는 보수적인 기술이라는 것이 문제점으로 작용하고 있다. 특히 정부발 프로젝트에 기대는 SI 회사가 절대 다수를 차지하는 현실로 인해 한국의 SW 시장이 Java + Spring으로 획일화되다시피 하는 결과를 낳았으며, 이는 곧 국내 소프트웨어 기술력 자체의 저하로 이어졌다. SI는 기본적으로 안정성과 유지보수를 추구하는 업계이지, 새로운 기술과 변화를 추구하는 곳이 아니기 때문. 그런데 사용하는 프레임워크와 제반 기술들까지 일원화되니 다양성이 죽어버린 것이다. 그나마 삼성전자와 네이버 등의 극소수 대기업들이 어느 정도 커버를 하는 상황.

 

ArrayList vs LinkedList

ArrayList:

배열 기반 구현: ArrayList는 내부적으로 배열을 사용하여 데이터를 저장합니다. 이는 인덱스를 사용한 빠른 접근을 가능하게 합니다.

고정된 크기가 아님: 크기가 동적으로 조절될 수 있으며, 요소를 추가하면 자동으로 크기가 늘어납니다.

랜덤 액세스가 빠름: 배열 기반이므로 인덱스를 사용한 랜덤 액세스가 매우 빠릅니다.

메모리 사용: 크기를 동적으로 조절할 수 있지만, 미리 큰 크기로 할당되므로 메모리 소요가 크다.

요소 삽입/삭제가 느림: 중간에 요소를 삽입하거나 삭제할 때는 이후의 모든 요소를 이동시켜야 하므로 성능이 떨어집니다.


LinkedList:

링크드 리스트 기반 구현: LinkedList는 노드들이 링크로 연결된 구조를 사용하여 데이터를 저장합니다.
크기가 동적으로 조절됨: 크기가 동적으로 조절될 수 있으며, 요소를 추가하면 크기가 늘어납니다.
랜덤 액세스가 느림: 인덱스를 사용한 랜덤 액세스가 배열에 비해 느립니다. 특정 인덱스에 직접 접근하는 데 O(n)의 시간이 소요됩니다.
요소 삽입/삭제가 빠름: 중간에 요소를 삽입하거나 삭제할 때, 해당 위치의 노드만을 조절하면 되므로 ArrayList에 비해 빠릅니다.
메모리 사용: ArrayList보다 많은 메모리를 사용합니다. 각 노드는 데이터와 다음 노드를 가리키는 링크를 가지고 있어 추가적인 메모리가 필요합니다.

 

 

MyBatis에서 $와 #는 SQL 템플릿 내에서 파라미터 값을 삽입하는 데 사용되는 두 가지 다른 표현식입니다.

 

1. $ (Dollar Sign): 동적 SQL 삽입


$를 사용하면 파라미터 값을 문자열로 치환합니다. 이는 동적 SQL을 생성할 때 유용합니다.
주어진 값이 문자열이나 숫자 등의 단순한 값이더라도, 값이 직접 치환되므로 SQL Injection 공격에 노출될 수 있습니다. 이를 방지하기 위해서는 사용자 입력을 쿼리에 직접 삽입하지 말고, 파라미터 바인딩을 통해 사용해야 합니다.

예제:
xml
Copy code
<!-- 동적 SQL 쿼리 -->
<select id="getUserById" parameterType="int" resultType="User">
  SELECT * FROM users WHERE id = ${userId}
</select>

 

2. # (Hash): 파라미터 바인딩:

#는 파라미터를 바인딩하는 용도로 사용됩니다. MyBatis는 이를 처리하여 JDBC Prepared Statement에 안전하게 바인딩됩니다.

자동으로 타입 매핑: #를 사용하면 MyBatis가 자동으로 파라미터의 타입에 맞게 치환해줍니다.

예제:
xml
Copy code
<!-- 파라미터 바인딩 -->
<select id="getUserById" parameterType="int" resultType="User">
  SELECT * FROM users WHERE id = #{userId}
</select>

parameterType은 "int"로 지정되어 있으므로, MyBatis는 #{userId}를 int로 자동으로 매핑

 

차이점:
SQL Injection:
$: 사용자로부터 입력 받은 값을 그대로 치환하므로 주의가 필요합니다.
#: MyBatis가 파라미터 값을 적절한 타입으로 치환해주기 때문에 SQL Injection 공격에 안전합니다.

 

Prepared Statement:
$: 값을 직접 치환하기 때문에 Prepared Statement의 이점을 활용할 수 없습니다.
#: JDBC Prepared Statement에 안전하게 값을 바인딩하여 SQL Injection을 방지하고 성능을 최적화합니다.
일반적으로는 #를 사용하는 것이 안전하며, SQL Injection 공격을 방지하고 타입 매핑 등의 장점을 활용할 수 있습니다. 그러나 동적으로 SQL을 생성해야 하는 경우 등 특별한 상황에서 $를 사용할 수도 있습니다.

 

 

 

"Keep-Alive"와 "HTTP Keep-Alive"

 

"Keep-Alive"와 "HTTP Keep-Alive"는 네트워크 통신에서 연결을 재사용하여 성능을 향상시키는 목적으로 사용되는 두 가지 관련된 개념입니다.

1. Keep-Alive:
일반적인 의미: "Keep-Alive"는 네트워크 연결을 유지하고 활성 상태로 유지하는 메커니즘을 나타냅니다.
TCP 연결 유지: TCP 연결은 유지되며, 서버 및 클라이언트 간의 추가 요청 및 응답을 위해 연결을 재사용합니다.
다양한 응용: 웹 서버, 데이터베이스 연결 등 다양한 응용 분야에서 사용될 수 있습니다.

2. HTTP Keep-Alive:
HTTP 특정 개념: "HTTP Keep-Alive"는 HTTP 프로토콜에서 사용되는 Keep-Alive 메커니즘을 나타냅니다.
HTTP 연결 재사용: HTTP Keep-Alive는 단일 TCP 연결을 통해 여러 HTTP 요청과 응답을 처리할 수 있도록 합니다.
성능 향상: 여러 요청에 대해 새로운 TCP 연결을 설정하는 대신 기존의 연결을 유지하고 재사용함으로써 성능을 향상시킬 수 있습니다.

차이점:
적용 범위:
Keep-Alive: 네트워크 레벨에서 연결을 유지하고 활성 상태로 유지하는 메커니즘으로, TCP 연결의 일반적인 개념입니다.
HTTP Keep-Alive: HTTP 프로토콜에서 사용되는 Keep-Alive로, HTTP 연결을 재사용하여 성능을 향상시키는 기술입니다.

 

사용 목적:
Keep-Alive: 다양한 네트워크 응용 분야에서 사용됩니다.
HTTP Keep-Alive: 주로 웹 서버와 웹 브라우저 간의 통신에서 사용됩니다.

 

구체적인 동작:
Keep-Alive: 연결을 닫지 않고 유지하는 일반적인 원칙입니다.
HTTP Keep-Alive: HTTP 연결을 닫지 않고 재사용하여 여러 HTTP 요청을 처리합니다.


=> 둘 다 연결을 재사용하여 성능을 향상시키는 목적으로 사용되지만, "HTTP Keep-Alive"는 HTTP 프로토콜에서 특히 사용되며, 일반적인 "Keep-Alive"는 네트워크 레벨에서의 연결 유지를 의미합니다.

 


웹 소켓(WebSocket)


웹 소켓(WebSocket)은 양방향 통신을 지원하는 네트워크 프로토콜로, 클라이언트와 서버 간의 실시간 양방향 통신을 가능하게 합니다. 일반적인 HTTP 프로토콜과는 다르게, 웹 소켓은 계속 연결된 상태로 데이터를 주고받을 수 있어 실시간 통신에 적합합니다.

웹 소켓의 특징:
양방향 통신: 클라이언트와 서버 간에 양방향으로 데이터를 주고받을 수 있습니다.
실시간 통신: 연결이 지속되므로 실시간으로 데이터를 전송할 수 있습니다.
효율적인 통신: HTTP와 달리 항상 연결을 새로 맺지 않고, 이미 열린 연결을 재사용하여 데이터를 주고받아 효율적인 통신이 가능합니다.
낮은 지연 시간: TCP를 기반으로 하며, 여러 계층을 거치지 않고 직접 통신하므로 지연 시간이 낮습니다.

 

웹 소켓 연결 과정:
핸드쉐이크 (Handshake):
클라이언트가 서버에 웹 소켓 연결을 요청하면, 서버와 클라이언트 간에 핸드쉐이크가 이루어집니다.
핸드쉐이크를 통해 클라이언트와 서버는 웹 소켓 연결에 동의하고, 연결에 필요한 정보를 교환합니다.

 

연결 설정: 핸드쉐이크가 완료되면, 서버와 클라이언트 간에 양방향 연결이 설정됩니다.

 

데이터 송수신: 연결이 설정되면, 양쪽에서 데이터를 주고받을 수 있습니다.
클라이언트나 서버에서 데이터를 보내면, 상대편은 이를 받아 처리하고 필요에 따라 응답을 보낼 수 있습니다.

 

연결 종료: 통신이 끝나면 클라이언트나 서버는 연결을 종료할 수 있습니다. 연결이 종료되면 핸드쉐이크 등의 과정을 통해 다시 연결할 수 있습니다.

 


웹 소켓 API:
자바스크립트에서는 WebSocket API를 통해 웹 소켓을 사용할 수 있습니다. 

주요 메서드로는 onopen, onmessage, onclose, send 등이 있습니다. 

[자바스크립트]
// 웹 소켓 생성
const socket = new WebSocket("ws://example.com/socket");

// 연결이 열렸을 때의 이벤트 핸들러
socket.onopen = function (event) {
  console.log("WebSocket 연결이 열렸습니다.");
};

// 메시지 수신 시의 이벤트 핸들러
socket.onmessage = function (event) {
  console.log("서버로부터 메시지 수신:", event.data);
};

// 연결이 닫혔을 때의 이벤트 핸들러
socket.onclose = function (event) {
  console.log("WebSocket 연결이 닫혔습니다.");
};

// 메시지 전송
socket.send("안녕하세요, 서버에게 메시지 보내기");

 

자바에서는 javax.websocket 패키지를 통해 웹 소켓을 사용가능
자바 서버 코드

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;

@ServerEndpoint("/websocket")
public class WebSocketServer {

    @OnOpen
    public void onOpen(Session session) {
        System.out.println("WebSocket 연결이 열렸습니다.");

        // 클라이언트에게 메시지 전송 예제
        sendMessage(session, "안녕하세요, 클라이언트!");
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("클라이언트로부터 메시지 수신: " + message);

        // 클라이언트에게 응답 메시지 전송 예제
        sendMessage(session, "서버에서 응답: " + message);
    }

    @OnClose
    public void onClose(Session session) {
        System.out.println("WebSocket 연결이 닫혔습니다.");
    }

    @OnError
    public void onError(Throwable error) {
        System.err.println("WebSocket 오류 발생: " + error.getMessage());
    }

    private void sendMessage(Session session, String message) {
        try {
            session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

자바 클라이언트 코드

import javax.websocket.ClientEndpoint;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import java.net.URI;

@ClientEndpoint
public class WebSocketClient {

    @OnOpen
    public void onOpen() {
        System.out.println("WebSocket 연결이 열렸습니다.");
    }

    @OnMessage
    public void onMessage(String message) {
        System.out.println("서버로부터 메시지 수신: " + message);
    }

    public static void main(String[] args) {
        try {
            URI uri = new URI("ws://localhost:8080/your-context-path/websocket"); // 웹 소켓 서버 주소
            javax.websocket.WebSocketContainer container = ContainerProvider.getWebSocketContainer();
            container.connectToServer(WebSocketClient.class, uri);

            // 웹 소켓 연결이 열린 후에 원하는 작업 수행 가능

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


웹 소켓은 주로 실시간 채팅, 실시간 게임, 주식 시장 데이터 업데이트 등 실시간 통신이 필요한 상황에서 사용