반응형

 

R2dbc

jasync-sql

'JAVA' 카테고리의 다른 글

CentOS File 인코딩  (0) 2021.11.30
JAVA CS핵심 내용  (0) 2021.03.10
restful API 규칙  (0) 2021.03.03
java 리스트간 비교, 값 체크  (0) 2021.02.24
Kafka  (0) 2021.02.24
반응형

$ iconv -f "현재인코딩포맷" -t "바꿀인코딩포맷" "원본파일이름" > "저장할파일이름"

iconv -f euc-kr -t utf-8 test.txt > test_result.txt

 

'JAVA' 카테고리의 다른 글

WebFlux 비동기 Reactive JDBC  (0) 2022.07.05
JAVA CS핵심 내용  (0) 2021.03.10
restful API 규칙  (0) 2021.03.03
java 리스트간 비교, 값 체크  (0) 2021.02.24
Kafka  (0) 2021.02.24
반응형

빌드를 하다보면 Gradle 로 빌드를 하게되어 개발 테스트시 속도가 저하될수있다.

 

File | Settings | Build, Execution, Deployment | Build Tools | Gradle 들어가서
Build and run using 을 IntelliJ 로 변경시 IntelliJ 로 빌드를 진행 할수있다.

'JAVA > Java' 카테고리의 다른 글

JAVA private static final, private final 차이  (0) 2021.06.01
Intellij 라인 번호, 공백 표시  (0) 2021.05.17
Spring Cloud Netflix  (0) 2020.03.18
OAuth2  (0) 2020.03.18
정규식 표현(Regular Expression)이란?  (0) 2019.11.29
반응형

상수를 사용할때 private static final, private final 차이

private static final Integer THREAD_COUNT = 10;

private final Integer THREAD_COUNT = 10;


- private static final을 선언한 변수를 사용하면 재할당하지 못하며, 메모리에 한 번 올라가면 같은 값을 클래스 내부의 전체 필드, 메서드에서 공유한다.

- private final을 선언한 변수를 사용하면 재할당하지 못하며, 해당 필드, 메서드별로 호출할 때마다 새로이 값이 할당(인스턴스화)한다.

 

그렇다면 상수로 사용하려고 할 때, 그 값은 변하지않는 값을 호출할 때마다 새롭게 인스턴스화 하여 올릴필요가 없다.
private static final 로 상수가 선언된 부분을 메모리에서 가져다 쓰면된다.

 

'JAVA > Java' 카테고리의 다른 글

IntelliJ Gradle Run 변경  (0) 2021.06.08
Intellij 라인 번호, 공백 표시  (0) 2021.05.17
Spring Cloud Netflix  (0) 2020.03.18
OAuth2  (0) 2020.03.18
정규식 표현(Regular Expression)이란?  (0) 2019.11.29
반응형

1. 라인번호

File | Settings | Editor | General | Appearance 
- Show line numbers 체크

 

2. 공백 표기
File | Settings | Editor | General | Appearance 
- Show whitespaces 체크

'JAVA > Java' 카테고리의 다른 글

IntelliJ Gradle Run 변경  (0) 2021.06.08
JAVA private static final, private final 차이  (0) 2021.06.01
Spring Cloud Netflix  (0) 2020.03.18
OAuth2  (0) 2020.03.18
정규식 표현(Regular Expression)이란?  (0) 2019.11.29
반응형

객체지향의 특징

  • Abstraction(추상화)
  • : 현상에 존재하는 객체의 주요 특징을 추출하는 과정.
  • Encapsulation(캡슐화)
  • : 하나의 클래스 안에 데이터, 기능을 담아 정의하고(속성), 중요한 데이터나 복잡한 기능 등은 숨기고(private/protected), 외부에서 사용에 필요한 기능만을 공개하는 것.
  • Inheritance(상속)특정 Class를 상속 받아 그 Class의 변수와 기능을 재사용한다. Java에서는 다중상속이 불가능하다.
    • Generalization : 추출된 class의 공통적인 특성을 모아 super class로 정의.
    • Specialization : 비슷한 속성과 기능을 가지고 있는 다른 class를 상속받아 새로운 class를 정의할 수 있음.
  • sub객체 생성 시 super도 함께 생성된다.
  • : 객체 정의 시 기존에 존재하는 객체의 속성과 기능을 상속받아 정의 하는 것.
  • Polymorphism(다형성): 같은 타입의 변수가 다양한 형태의 객체를 참조하는 것.Member mem = new Member(); Member memc = new MainMember();
    • 장점
    • super 클래스와 sub클래스를 다형성에 의해 super 클래스 타입으로 한꺼번에 관리 및 저장 가능.
  • 즉, super타입의 변수가 다양한 sub타입을 참조하는 것을 의미한다.
  • : 상속이 전제가 되어야 한다. 같은 타입 또는 같은 기능의 호출로 다양한 효과를 가져오는 것.
      • 객체지향의 5가지 법칙 (SOLID)
        • Single Responsibility Principle, 단일 책임 법칙
          각 클래스는 목적을 하나씩만 가지고 그에 대한 책임을 져야 한다.
        • Open Close Principle, 개방 폐쇄 법칙
          각 클래스는 클래스에 대한 수정을 폐쇄하고, 확장에 대해 개방해야 한다.
          즉 클래스를 수정해야 한다면 그 클래스를 상속, 즉 확장하여 수정한다.
        • Liskov Substitusion Principle, 리스코프 치환 법칙
          자식 클래스를 사용 중일때, 거기에 부모 클래스로 치환하여도 문제가 없어야 한다.
        • Interface Segreation Principle, 인터페이스 분리 법칙
          각 행위에 대한 인터페이스는 서로 분리되어야 한다.
          핸드폰을 예로 들면, 전화를 하는데 핸드폰 카메라가 방해가 되면 안된다는 말.
        • Dependency Inversion Principle, 의존성 역전 법칙
          상위 클래스가 하위 클래스에 의존하면 안된다는 법칙. 즉 기본적인 공통되는 속성을 하위 클래스에 의존하면 안된다.
      • Interface 란
        interface라고 쓰는 이 인터페이스는 결론부터 얘기하면 '공동 작업시 충돌을 방지하기 위해서'라고 한다.
        자바의 다형성을 극대화하여 개발코드 수정을 줄이고 프로그램 유지보수성을 높이기 위해

      • 추상클래스란
         클래스들의 공통되는 필드와 메소드를 정의한 클래스를 말한다.

      • 추상 클래스 및 메소드 특징
        1. 자체적으로 객체를 생성할 수 없다. 따라서 상속을 통해 자식 클래스에서 인스턴스를 생성해야 한다.
        2. 추상 클래스는 추상 메소드, 일반 메소드, 필드(멤버변수), 생성자로 구성된다.
        3. 일반적인 상속의 특성과 동일하다.(extends 이용, 단일 상속, 생성자 호출 등)
        4. 추상 클래스를 상속받는 클래스는 추상 메소드를 반드시 오버라이딩(overriding) 해야 한다.
        5. 오버라이딩 할 때 abstract를 제외한 시그니처를 클래스에서 동일하게 적어줘야 한다.

      • interface의 default 메서드
        - interface에서도 메서드 구현이 가능합니다
        - 참조 변수로 함수를 호출할 수 있습니다.
        - implements 한 클래스에서 재정의가 가능합니다

      • interface의 static 메서드 
        - interface에서 메서드 구현이 가능합니다
        - 반드시 클래스 명으로 메서드를 호출해야 합니다.
        - 재정의 불가능!

      • public interface CalculatorInterface {
            int add(int x, int y);
            int sub(int x, int y);
            
            default int mul(int x, int y) {
                return x * y;
            }
            
            static String value(int i) {
        		return String.valueOf(i);
        	}
        }
        
        public class Calculator implements CalculatorInterface {
         
            @Override
            public int add(int x, int y) {
                return x + y;
            }
         
            @Override
            public int sub(int x, int y) {
                return x - y;
            }
        }
        
        public class CalculatorTest {
        
        	@Test
        	public void 인터페이스_mul_확인() {
        		Calculator calculator = new Calculator();
        		Assert.assertEquals(calculator.mul(2, 5), 10);
        	}
        
        	@Test
        	public void 인터페이스_static_value_확인() {
        		Assert.assertEquals(CalculatorInterface.value(10), "10");
        	}
        }
        

메모리 구조

  • Class Area(=Method Area) : 메모리로 읽어온 클래스의 정보를 기억한다.
  • heap : 클래스의 객체를 생성하여 기억한다.
  • stack : 메소드 수행 시마다 프레임이 할당되어 메서드 수행에 필요한 변수나(로컬변수), 중간 결과 값을 임시 기억한다. 메소드가 종료될 경우 할당된 메모리가 자동 제거된다.

Garbage Collector(GC)

자바는 메모리 관리를 개발자가 아닌 GC(Garbage Collector)라는 쓰레드를 생성하여 사용하지 않는 객체들을 제거한다.

일반적으로 자바에서는 JVM에 의해 자동으로 Garbage Collection이 실행된다. 더 이상 사용되지 않은 객체들을 점검하여 제거한다.

GC(Garbage Collection)

  • Heap영역(class 영역 포함)에 생성된 객체들의 메모리 관리를 담당하는 프로그램.
  • 더 이상 사용되지 않은 객체들을 점검하여 제거한다.
  • JVM에 의해 자동적으로 실행되며, CPU가 한가하거나 메모리가 부족할 때 실행된다.
  • GC를 수행하는 동안 GC를 수행하기 위한 Thread 이외의 모든 Thread 작업이 멈추기 때문에 시스템에 큰 영향을 미치게 된다.

스프링부트

Spring Boot는 개발의 simpify를 최우선으로 한 java framework입니다.
Spring Boot는 Spring MVC 기반의 Java Web 개발을 더 쉽게 만들어주는 특징은 다음과 같습니다.

  • auto-configuration
  • embedded servlet container
  • starter-dependencies
  • Actuator
  • Spring Boot CLI

Spring Boot와 Spring MVC의 차이점

둘 다, 스프링 프레임워크의 범주에 포함됩니다. 각각 다른 문제를 해결하기 위한 프레임워크입니다. 

Spring MVC는 Model-View-Controller 디자인패턴을 사용하는 일관된 구조를 제공함으로써 자바 웹 개발을 쉽게 하게 해줍니다. 반면, 스프링부트는 Spring MVC를 포함하는 Spring framework를 가지고 웹 개발을 하면서 가지는 고통스러운 설정, 의존성 관리 그리고 애플리케이션 실행을 더 간편하고 쉽게 개발하게 해줍니다.

Spring Boot 장점

- starter를 통한 자동 권장 버전 관리, 편리한 의존성 관리
- 내장서버가 있기때문에 jar 파일로 간단하게 배포 가능

IOC - 객체의 생성 생명주기의 관리까지 모든 객체에 대한 제어권이 바뀌었다는 것을 말합니다.
      객체를 생성 및 제거하는 것은 비용이 많이 들기 때문에 스프링 컨테이너에서 IOC를 구현해주어 자주 사용하는 객체를 제어함
DI - 의존성 주입으로 의존적인 객체를 직접 생성하거나 제어하는것이 아니라 외부에서 결정해서 연결시키는것
     @Componet 어노테이션으로 의존객체로 만들고 


AOP - 공통기능을 모든 모듈에 적용하기 위한 방법
- 관점지향프로그래밍 메소드 전 후 지점에 설정 가능하며 트랜잭션, 에러처리와 같은 기능에 적합함
       (로깅', '트랜잭션', '에러 처리')
     @Transactional, interceptor, filter aop의 일종
@Before: 대상 메서드의 수행 전
@After: 대상 메서드의 수행 후
@After-returning: 대상 메서드의 정상적인 수행 후
@After-throwing: 예외발생 후
@Around: 대상 메서드의 수행 전/후

Filter - 서블릿 필터는 DispatcherServlet 이전에 실행이 되는데 필터가 동작하도록 지정된 자원의 앞단에서 요청내용을 변경하거나,  여러가지 체크를 수행할 수 있다.

 init() - 필터 인스턴스 초기화
ㆍdoFilter() - 전/후 처리
ㆍdestroy() - 필터 인스턴스 종료

Interceptor - 컨트롤러를 호출하기 전 후단계에 대한 요청 응답에 대해 처리함 
              (로그인체크, 권한체크)
preHandler() - 컨트롤러 메서드가 실행되기 전
postHanler() - 컨트롤러 메서드 실행직 후 view페이지 렌더링 되기 전
afterCompletion() - view페이지가 렌더링 되고 난 후

 

Filter, Interceptor 차이

디스패처 핸들링 위치차이 필터는 dispatcher를 거치지 않고 인터셉터는 dispatcher를 거침
그렇기 때문에 filter에서는 pathvariable을
잡을 수가 없음
필터는 주로 인증관련에서 사용 인터셉터는 요청값 확인에 사용함

디자인패턴

싱글턴패턴 - 객체를 하나만 생성해서 생성된 객체를 어디에서든지 참조할수 있도록 하는 패턴 
         (고정된 메모리 영역을 얻으면서 한번의 new로 인스턴스를 사용하기 떄문에 메모리 낭비를 방지할수있음) 
       private로 외부에서 접근못하도록하고 instance 함수를 만들어 그 안에 new로 객체생성

전략패턴 - 객체가 할 수 있는 행위들 각각을 전략으로 만들어 놓고 수정이 필요한 경우 전략을 바꾸는 것만으로 행위의 수정이 가능하도록 만든 패턴입니다.

팩토리 메소드 패턴 - 객체를 생성하기 위한 인터페이스를 정의하는데, 어떤 클래스의 인스턴스를 만들지는 서브클래스에서 결정하게 만든다.

템플릿 메서드 패턴 - 서브 클래스로 캡슐화해 구조는 바꾸지 않고 상황에 맞게 서브클래스를 이용해 수행 내역을 변경해주는 패턴

커멘트패턴 - 실행될 기능을 캡슐화 함으로써 주어진 여러 기능을 실행할 수 있는 재사용성이 높은 클래스 설계하는 패턴

빌더패턴 - 여러개의 파라미터를 전달할때도 어떤한값이 어떤한 의미인지 파악할수 있어서 사용, 유지보수에 용이함
어댑터와 프록시 패턴(두 클랙스간에 하나의 클래스를 두는 구조)
차이점- 어댑터는 하나의 인터페이스에 맞추는게 목적이고 
      프록시는 다양한 방식으로 로직 컨트롤이 목적

타임리프 장점
- 템플릿 코드 자체가 html이기 때문에 뷰파일을 was없이도 브라우저에서 직접 띄워볼수가있음

Spring Boot @SpringBootApplication 내부

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)

대표적으로 @SpringBootConfiguration, @EnableAutoConfiguration ,@ComponentScan 3가지가있다.

  • @SpringBootConfiguration: 스프링 부트의 설정을 나타내는 어노테이션이다. 스프링의 @Configuration을 대체하며 스프링 부트 전용 어노테이션이다. 테스트 어노테이션을 사용할 때 계속 이 어노테이션을 찾기 때문에 스프링 부트에서는 필수 어노테이션이다.
  • @EnableAutoConfiguration: 자동 설정의 핵심 어노테이션이다. 클래스 경로에 지정된 내용을 기반으로 설정 자동화를 수행한다.
  • @ComponentScan: basePackages 프로퍼티 값에 별도의 경로를 설정하지 않으면 해당 어노테이션이 위치한 패키지가 루트 경로가 된다.

component configuration 차이

configuration  : 개발자가 직접 제어가 불가능한 외부 라이브러리 또는 설정을 위한 클래스를 Bean으로 등록할 때 @Bean 어노테이션을 활용

component : 개발자가 직접 개발한 클래스를 Bean으로 등록하고자 하는 경우 @Component 어노테이션을 활용

Bean 생명주기 (Lifecycle)

객체 생성 - 초기화 - 사용 - 소멸 순으로 유지된다.

GC
- heap영역의 오브젝트 중 stack에서 도달 불가능한 오브젝트들은 가비지 컬렉션의 대상이됨

auto-configuration

Spring Boot auto-configuration가 classpath를 체크합니다. 체크해서 예를 들어 thymeleaf가 있으면,  Thymelead template resolver, view resolver, and a template engine 이 것들을 자동으로 설정해 줍니다.

만약, Spring Data JPA가 classpath에 있으면, 자동으로 repository interface들로부터 repository implementations를 만들어줍니다.

Spring Boot Starter Dependency

Starter dependency란?

starter dependency는 스프링부트에서 의존성 관리 문제를 해결해주는 역할을 합니다. 우리가 스프링부트를 사용할 때, JPA나 Thymeleaf Template가 현재 프로젝트에 적합한 버전이 무엇인지 알아야하거나  필요한 의존성 리스트를 상세하게 알 필요가 없습니다. 단지 Gradle이나 Maven build file에 추가해주면됩니다.

starter가 Maven이나 Gradle file에 등록한 의존성jar를 자동으로 프로젝트에 로드해 줍니다.
spring-boot-starter-web를 의존성 추가하면, Spring MVC Jar를 프로젝트에 import합니다.

 

스프링부트에서 properties정의

 application.properties파일에 정의하면 되고, springboot가 자동으로 읽습니다. 예로 server.port=9000으로 하면, 내장 톰켓이 실행되면, 디폴트 8080이 아니라 9000으로 앱이 실행됩니다.

 

YML

YAML(야믈, 와이엠엘(.yml))은 JSON의 상위집합(superset)으로, 계층적 뼈대 구조를 설정하는데 편리한 형식(format)입니다. SpringApplication은 classpath에 있는 SnakeYAML library를 가지고 있을 때, 속성(properties)의 대안으로 자동적으로 YAML을 지원합니다.

spring-boot-starter는 가장 기본적인 라이브러리고, 이것이 있으면 SnakeYAML 은 자동으로 제공됩니다.

 

JAVA8 Stream

JDK 8에서 추가된 Stream API

컬렉션, 배열등의 저장 요소를 하나씩 참조하며 함수형 인터페이스(람다식)를 적용하며 반복적으로 처리할 수 있도록 해주는 기능

 

POJO(Plain Old Java Object)

POJO는 말 그대로 해석을 하면 오래된 방식의 간단한 자바 오브젝트 
쉽게 생각해서 순수한 자바 오브젝트라고 생각하면된다 
예) getter, setter 가 메소드로 이루어진 Value Object 라고 생각하면된다.

 

비동기 (Asynchronous: 동시에 일어나지 않는, 非同期: 같은 시기가 아닌)

비동기란 말 그대로 동시에 일어나지 않는다는 의미한다.
즉, 요청과 결과가 동시에 일어나지 않아 바로 결과가 주어지지 않고 나중에 처리된다

동기 (synchronous: 동시에 일어나는, 同期: 같은 시기)

동기란 비동기와 반대로 동시에 일어난다는 말한다. 따라서 요청과 그 결과가 동시에 일어나서 
요청을 하면 바로 그 요청한 자리에서 결과가 주어지며
시간이 얼마가 걸리든 상관 안하고 요청한 그 자리에서 결과를 주겠다는 약속같은 것이다.
즉, 요청과 결과가 한자리에서 동시에 일어난다

* 이렇게 동기와 비동기를 구분하는 이유는
동기와 비동기를 굳이 구분하는 이유는 상황에 따라서 장단점이 있기 때문인데
동기방식은 매우 설계가 간단하고 직관적이지만, 결과가 주어질 때까지 아무것도 못하고 대기해야 하는 단점이있고
비동기방식은 좀더 복잡하지만 결과가 주어지는 시간이 길어져도 그 시간 동안 다른 작업을 할 수 있으므로 좀더 효율적으로 자원을 사용할 수 있는 장점이있다

블로킹(Blocking)

블로킹은 말 그대로 작업이 중단된다는 의미. 네트워크 통신에서 요청이 발생하고 완료될 때까지 모든 일을 중단한 상태로 대기해야 하는 것을 블로킹 방식이라 한다.

논블로킹(Non-blocking)

논블러킹은 말 그대로 중단되지 않는다는 말. 통신이 완료 될 때까지 중단되는 블로킹의 반대 개념이다.
논블로킹 방식은 아무래도 통신이 완료될 때까지 기다리지 않고 다른 작업을 수행할 수 있으므로 경우에 따라 효율이나 반응속도가 더 뛰어나다.

동기/비동기 와 블로킹/논블로킹의 조합

REST 란

REST 란 “Representational State Transfer” 의 약자이다. 월드 와이드 웹과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식이다.

REST란, “웹에 존재하는 모든 자원(이미지, 동영상, DB 자원)에 고유한 URI를 부여해 활용하는 것으로, 자원을 정의하고 자원에 대한 주소를 지정하는 방법론을 의미한다고 한다.

이런 REST의 형식을 따른 시스템을 RESTful 이라고 부른다.
HTTP URI 를 통해 자원을 명시하고 HTTP Method를 통해 해당 자원의 대한 CRUD Operation을 적용한다.

 

WebFlux

 적은 양의 스레드와 최소한의 하드웨어 자원으로 동시성을 핸들링하기 위해 만들어졌다. 서블릿 3.1이 논블로킹을 지원하지만, 일부분이다. 이는 새로운 공통 API가 생긴 이유가 됐으며, netty와 같은 잘 만들어진 async, non-blocking 서버를 사용한다.

비동기 논블로킹 환경에서 자리를 잡은 서버(e.g. Netty) spring 버전이라고 생각하면된다.

  • 비동기 - 논블록킹 리액티브 개발에 사용
  • 효율적으로 동작하는 고성능 웹어플리케이션 개발
  • 서비스간 호출이 많은 마이크로서비스 아키텍처에 적합

Mono와 Flux

 Mono는 0-1개의 결과만을 처리하기 위한 Reactor의 객체이고, Flux는 0-N개인 여러 개의 결과를 처리하는 객체입니다.

vert.x

NodeJS와 같은 비동기 소켓서버 프레임워크
Vert.x는 nodejs와 마찬가지로 single thread model이며

 

리액티브 프로그래밍

데이터 흐름과 전달에 관한 프로그래밍 패러다임

데이터 흐름을 먼저 정의하고 데이터가 변경되었을 때 연관되는 함수나 수식이 업데이트되는 방식

사용자 입장에서 보자면 Reactive Programming이란 실시간으로 반응을 하는 프로그래밍을 말합니다. 예를 들면, 네이버 검색창에 단어를 하나씩 입력할 때마다 관련 검색어들이 자동완성으로 바로바로 제시되는 것이나, 페이스북 포스트에 '좋아요' 버튼을 누르면 해당 포스트를 보고 있는 다른 유저의 '좋아요' 카운트가 페이지 새로 고침이 없어도 실시간으로 올라가는 것을 말합니다.

 

세션과 쿠키 차이

  • 저장 위치
    • 쿠키는 클라이언트(브라우저)에 메모리 또는 파일에 저장하고, 세션은 서버 메모리에 저장된다.
  • 보안
    • 쿠키는 클라이언트 로컬(local)에 저장되기도 하고 특히 파일로 저장되는 경우 탈취, 변조될 위험이 있고, Request/Response에서 스나이핑 당할 위험이 있어 보안이 비교적 취약하다. 반대로 Session은 클라이언트 정보 자체는 서버에 저장되어 있으므로 비교적 안전하다.
  • 라이프 사이클
    • 쿠키는 앞서 설명한 지속 쿠키의 경우에 브라우저를 종료하더라도 저장되어 있을 수 있는 반면에 세션은 서버에서 만료시간/날짜를 정해서 지워버릴 수 있기도 하고 세션 쿠키에 세션 아이디를 정한 경우, 브라우저 종료시 세션아이디가 날아갈 수 있다.
  • 속도
    • 쿠키에 정보가 있기 때문에 쿠키에 정보가 있기 때문에 서버에 요청시 헤더를 바로 참조하면 되므로 속도에서 유리하지만, 세션은 제공받은 세션아이디(Key)를 이용해서 서버에서 다시 데이터를 참조해야하므로 속도가 비교적 느릴 수 있다.

 

프레임워크와 라이브러리 차이

프레임워크는 전체적인 흐름을 자체적으로 가지고 있어 프로그래머는 그 안에서 필요한 코드를 작성합니다. 반면에 라이브러리는 프로그래머가 전체적인 흐름을 가지고 있어 라이브러리를 자신이 원하는 기능을 구현하고 싶을 때 가져다 사용할 수 있다

 

HTTP 1.0 1.1 차이

1. 커넥션 유지
- 1.0은 요청마다 TCP 세션을 맺어야 한다.
(1 GET / 1Connection)
- 1.1 은 Persistent 기능을 이용하여 TCP 세션을통해 여러개의 컨텐츠 요청이 가능하다.
(N GET / 1Connection)


2. 호스트 헤더
- 버추얼 호스팅을 지원한다
(여러개의 도메인으로 하나의 서버에 접근가능)


3. 강력한 인증 절차
프록시가 사용자인증을 요구하는헤더가 생성되었다.

  • proxy-authentication
  • proxy-authorization

 

제네릭을 사용하는 이유?

  • 컴파일 시 강한 타입 체크를 할 수 있습니다.
    자바 컴파일러 코드에서 잘못 사용된 타입 때문에 발생하는 문제점을 제거하기 위해 제네릭 코드에 대한 강한 타입 체크를 합니다. 실행 시 타입 에러가 나는 것보다는 컴파일 시에 미리 타입을 강하게 체크해서 에러를 사전에 방지하는 것이 좋습니다.
  • 타입 변환을 제거합니다.
    비제네릭 코드는 불필요한 타입 변환을 하기 때문에 프로그램 성능에 악영향을 미칩니다. 다음 아래 코드를 보면 List에 문자열 요소를 저장했지만, 요소를 찾아올 때는 반드시 String으로 타입 변환을 해야합니다.

 

'JAVA' 카테고리의 다른 글

WebFlux 비동기 Reactive JDBC  (0) 2022.07.05
CentOS File 인코딩  (0) 2021.11.30
restful API 규칙  (0) 2021.03.03
java 리스트간 비교, 값 체크  (0) 2021.02.24
Kafka  (0) 2021.02.24
반응형

안녕하세요. 오늘은 restful api의 규칙을 알아봅시다.

 

REST 란 ?

REST 란 “Representational State Transfer” 의 약자이다. 월드 와이드 웹과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식이다.

REST란, “웹에 존재하는 모든 자원(이미지, 동영상, DB 자원)에 고유한 URI를 부여해 활용하는 것으로, 자원을 정의하고 자원에 대한 주소를 지정하는 방법론을 의미한다고 한다.

이런 REST의 형식을 따른 시스템을 RESTful 이라고 부른다.

HTTP URI 를 통해 자원을 명시하고 HTTP Method를 통해 해당 자원의 대한 CRUD Operation을 적용한다.

CRUD Operation , HTTP Method

  1. Create : POST (자원 생성)
  2. Read : GET (자원의 정보 조회)
  3. Update : PUT (자원의 정보 업데이트)
  4. Delete : DELETE (자원 삭제)

REST 의 특징

  1. 클라이언트 / 서버 구조 (Client-Server)
    자원이 있는 Server , 자원을 요청하는 Client의 구조를 가진다.
  2. 무상태 (Stateless)
    HTTP는 Stateless 프로토콜 이므로 REST 역시 무상태성을 가진다. 클라이언트의 Context 를 서버에 저장하지 않는다.
  3. 캐시 처리 가능 (Cachealble)
    웹 표준 HTTP 프로토콜을 그대로 사용하므로 , 웹에서 사용하는 기존의 인프라를 그대로 활용 가능하다.
  4. 계층화
    API 서버는 순수 비즈니스 로직을 수행하고 그 앞단에 사용자 인증 , 암호화 , 로드밸런싱 등을 하는 계층을 추가하여 구조상의 유연성을 줄 수 있다.
  5. 인터페이스 일관성(Uniform Interface)
    URI로 지정한 자원에 대한 조작을 통일되고 한정적인 인터페이스로 수행한다. HTTP 표준에만 따른다면 모든 플랫폼에 사용이 가능하다.
  6. 자체 표현 구조
    동사(Method) + 명사(URI) 로 이루어져있어 어떤 메서드에 무슨 행위를 하는지 알 수 있으며 REST API 자체가 매우 쉬워서 API 메세지 자체만 보고도 API를 이해할 수 있다

REST의 장단점

장점

  1. 쉬운 사용
    HTTP 프로토콜 인프라를 그대로 사용하므로 별도의 인프라를 구축할 필요가 없다.
  2. 클라이언트-서버 역할의 명확한 분리
    클라이언트는 REST API를 통해 서버와 정보를 주고받는다. REST의 특징인 Stateless에 따라 서버는 클라이언트의 Context를 유지할 필요가 없다.
  3. 특정 데이터 표현을 사용가능
    REST API는 헤더 부분에 URI 처리 메소드를 명시하고 필요한 실제 데이터를 ‘body’에 표현할 수 있도록 분리시켰다. JSON , XML 등 원하는 Representation 언어로 사용 가능하다.

단점

  1. 메소드의 한계
    REST는 HTTP 메소드를 이용하여 URI를 표현한다. 이러한 표현은 쉬운 사용이 가능하다는 장점이 있지만 반대로 메소드 형태가 제한적인 단점이 있다.
  2. 표준이 없음
    REST는 설계 가이드 일 뿐이지 표준이 아니다. 명확한 표준이 없다.

 

REST의 설계

REST API 설계시 가장 중요한 항목은 아래 두가지이다.

  1. URI는 정보의 자원을 표현해야 한다는 점
  2. 자원에 대한 행위는 HTTP Method(GET, POST, PUT, DELETE)로 표현한다는 점


1. 소문자를 사용한다. 

주소에서 대소문자를 구분하므로, 카멜방식이 아닌 소문자를 사용하여 작성한다.

//안좋은 예
https://localhost:8080/ddoriya/user/getUsers

//좋은 예
https://localhost:8080/ddoriya/user/get-users

 

2. 가급적 하이픈 사용은 최소화하지만 정확한 표현을 위해 - 을 사용하여 사용구분을 만든다.

가급적 하이픈의 사용도 최소화하며, 정확한 의미나 표현을 위해 단어의 결합이 불가피한 경우에 사용한다.

//안좋은 예
https://localhost:8080/ddoriya/user/getUsers

//좋은 예
https://localhost:8080/ddoriya/user/get-users

 

3.파일 확장자는 URI에 포함시키지 않는다.

REST API에서는 메시지 바디 내용의 포맷을 나타내기 위한 파일 확장자를 URI 안에 포함시키지 않습니다. Accept header를 사용하도록 한다.

//안좋은 예
GET https://localhost:8080/ddoriya/user/photo.jpg

GET https://localhost:8080/ddoriya/user/photo 
HTTP/1.1 Host: restapi.example.com Accept: image/jpg



4. 가급적 전달하고자하는 자원의 명사를 사용하되, 컨트롤 자원을 의미하는 경우 예외적으로 동사를 허용한다.

//안좋은 예
https://localhost:8080/ddoriya/posts/duplicating

//좋은 예
https://localhost:8080/ddoriya/posts/duplicate



'JAVA' 카테고리의 다른 글

CentOS File 인코딩  (0) 2021.11.30
JAVA CS핵심 내용  (0) 2021.03.10
java 리스트간 비교, 값 체크  (0) 2021.02.24
Kafka  (0) 2021.02.24
RestTemplate VS WebClient  (0) 2021.02.24
반응형

리스트간 비교 anyMatch, noneMatch

문자열 비교에 따른 true, false 리턴

	@Test
	public void 리스트비교(){
		List<String> allList = new ArrayList<>();
		allList.add("1");
		allList.add("2");
		allList.add("3");

		List<String> comparisonList = new ArrayList<>();
		comparisonList.add("2");

		List<String> anyMatchList = allList.stream()
				.filter(target -> comparisonList.stream().anyMatch(Predicate.isEqual(target)))
				.collect(Collectors.toList());

		List<String> noneMatchList = allList.stream()
				.filter(target -> comparisonList.stream().noneMatch(Predicate.isEqual(target)))
				.collect(Collectors.toList());

		System.out.println(anyMatchList); // 2
		System.out.println(noneMatchList); // 1, 3
        
        
        //리스트에 값이 있는지 체크
        //1. for문으로 하였을 경우
        boolean isResult = false;
		for(String comparison : comparisonList){
			if(comparison.equals("2")){
				isResult = true;
				break;
			}
		}

		//2. stream 사용
		if (comparisonList.stream().anyMatch(w -> w.equals("2"))) {
			System.out.println("해당값이 있습니다.");
		}
        
	}

 

 

'JAVA' 카테고리의 다른 글

JAVA CS핵심 내용  (0) 2021.03.10
restful API 규칙  (0) 2021.03.03
Kafka  (0) 2021.02.24
RestTemplate VS WebClient  (0) 2021.02.24
비동기, 동기, 블로킹, 논블로킹  (0) 2021.02.19
반응형

 카프카는 메세지큐 서비스로 분산 환경에 특화 되있다고 한다. 보통 많이 알려진 RabbitMQ 와 동일한 메시지 큐지만 대용량 분석처리에 적합하다고 한다.

아직 ActiveMQ 밖에 사용해보지않았지만 개념으로 알아보도록하자

 

Kafka 특징 

- 분산 처리를 이용한 메세징 처리를 한다.   

  클러스터링 구조를 지원하고 단일 시스템 보다 성능이나 장애에 뛰어나며 데이터 유일이 없다.

- 시스템 확장에 용이하다. 

   분산시스템을 기반으로 설계 되었기 떄문에 확장에 아주 용이하다. 서비스를 중단하지 않고 무중단으로 확장이 가능하다. 

- 메세지를 메모리에 저장하지 않고 파일시스템에 저장한다. 

  RabbitMQ 같은 것들은 메모리에 보통 내용을 저장하고 있다가 메세지를 전송하고나면 메세지를 큐에서 삭제한다. 카프카는 데이터를 파일시스템에 저장한다. 그렇기 때문에 보관주기 안에는 메세지를 언제든지 읽어 가는게 가능하다. ( 기본 7일 ) 

- 배치 전송 처리 

  작은 메세지들은 묶어서 그룹핑 하여 처리 하여 네트워크상의 오버헤드를 줄임. 

 

Kafka 용어 

 

- Broker : 카프카가 설치된 서버 이다. 카프카 클러스터를 구성할경우 기본 1대 이상 서버들을 클러스터로 구성할수있다.

- Topic : 메세지들의 집합소이다. 프로듀서에서는 자신이 어느 토픽으로 메세지를 보낼지 정할수 있고 컨슈머는 어느 토픽에서 메세지를 가져올지 정할수 있다. 

 

- Partition : 로드 밸런싱을 위해서 토픽 자체를 분할 한다. 파티션은 하나의 프로듀서가 메세지를 전송시 여러개로 분할하여 날릴수 있는 데 메세지를 4개를 순차적으로 보내서 4초가 걸린다고 가정했을때 파티션을 4개로 파티션을 하여 전송하면 보다 빠른속도로 전송이 가능하다. ( 단, 메세지의 순서는 보장되어야한다는 제약조건이 있음. 오프셋을 사용하여 파티션  내부의 메세지를 식별함. ) 빠른 전송을 위해선 파티션이 필요하며 파티션만 늘리는것이 아니라 그수만큼 프로듀서의 수로 맞추어 늘려줘야만 제대로된 성능 효과를 볼수 있다.

 주의점은 파티션을 무한정으로 늘렸을 경우 자원낭비와 장애 발생시 복귀에 많은 자원이 소모 되므로 목표 처리량을 정해놓고 그에 맞게 설정을 해야한다.  ( 최대 파티션수는 2000개  ) 

- Replication : 브로커간의 메세지를 복사한다. 브로커중 리더가 메세지를 저장하면 리더가 아닌 다른 팔로워들이 그 데이터를 복사해서 가지고있는다. 리더에 문제가 생겼을시 다른 팔로워가 리더로 선출 되어도 동일 데이터를 들고 있기때문에 서비스에 영향이 없게 운영이 가능하다.

  ISR 을 이용하여 구성원과 리더를 구성하며 ISR 안에 속해 있어야만 리더선출 자격을 가진다. 

 

- Produce : 메세지를 카프카로 송신하는 주체 

  -   ack 설정 : 메세지 전달시 ack 설정에 따라 메세지 유실률과 처리량을 선택이 가능하다. 

      0 : ack 를 기다리지 않고 처리 , 유실률 ↑ 처리율 ↑

      1 : 리더는 데이터를 기록은 하지만 , 모든 팔로워들의 상태는 확인 하지 않음 , 유실률 - , 처리율 - 

     -1 : 모든 ISR 을 확인 함. 유실율 ↓ 처리율 ↓

  - 데이터를 보낼때 메세지 사이즈 크기와 메세지 보내기전 대기시간 , 대기 메모리량등을 프로듀서에서 설정이 가능하다. 

 

- Consumer : 메세지를 수신하는 주체 

- Apache Zookeeper : 분산 코디네이터 , 클러스트에 있는 서버들의 상태를 체크하고 분산시스템간의 정보 공유가 가능하도록 해주는 코디네이션 시스템 . 카프카 클러스터와 같으 사용시 기본적으로 주키퍼는 카프카 클러스터의 리더를 알고 있으며 시스템 구성시 카프카와 주키퍼는 다른 서버에서 구성하도록 한다. ( 주키퍼는 별도로 글을 작성 해야겠다 ) 

 

 

 

Kafka 사례 

 제일 유명한곳을 아래 두곳 같다. 국내에선  네이버나 카카오도 현재 사용중인것을 기술블로그 통해서 확인 했다. 실제 카프카 관련 서적 저자가 카카오에 계신 분인것도 확인했다. 국내에선 충분히 사용 가능할것 같고 활용도는 정말 아주 높을 것으로 보인다. 

안정성이나 성능보장성은  넷플릭스에서 서비스에 운영중이니 성능이나 안정성은 검증이 되지 않았나 싶다. 

이제 카프카를 시작한다. 카프카 단독으로도 충분히 좋은 플랫폼이라 생각하지만 적용 사례들만을 봐도 단순 카프카만으로 서비스를 하진 않는다. Spark , strom , Samza , hadoop 등 충분히 다른 플랫폼기술들과 연동이 가능하다고 본다. 단순 로그성 데이터를 수집하는것 이외에 실시간 데이터 추천이라든가 빅데이터를 수집하는 경우에도 충분히 활용하는게 가능할것 같다. 

 

'JAVA' 카테고리의 다른 글

restful API 규칙  (0) 2021.03.03
java 리스트간 비교, 값 체크  (0) 2021.02.24
RestTemplate VS WebClient  (0) 2021.02.24
비동기, 동기, 블로킹, 논블로킹  (0) 2021.02.19
JAVA11  (0) 2019.10.04
반응형

Spring 어플리케이션에서 HTTP 요청을 할 땐 주로 RestTemplate 을 사용했었습니다. 하지만 Spring 5.0 버전부터는 RestTemplate 은 유지 모드로 변경되고 향후 deprecated 될 예정입니다.

RestTemplate 의 대안으로 Spring 에서는 WebClient 사용을 강력히 권고하고 있으며 다음과 같은 특징을 가지고 있습니다.

  • Non-blocking I/O
  • Reactive Streams back pressure
  • High concurrency with fewer hardware resources
  • Functional-style, fluent API that takes advantage of Java 8 lambdas
  • Synchronous and asynchronous interactions
  • Streaming up to or streaming down from a server

Reactive 환경과 MSA를 생각하고 있다면 WebClient 사용을 적극 권장해 드리며, 기본 설정부터 Method 별 사용법까지 차근차근 알아보도록 하겠습니다.

1. RestTemplate이란?

spring 3.0 부터 지원한다. 스프링에서 제공하는 http 통신에 유용하게 쓸 수 있는 템플릿이며, HTTP 서버와의 통신을 단순화하고 RESTful 원칙을 지킨다. jdbcTemplate 처럼 RestTemplate 도 기계적이고 반복적인 코드들을 깔끔하게 정리해준다. 요청보내고 요청받는데 몇줄 안될 정도..

특징

  • 기계적이고 반복적인 코드를 최대한 줄여줌
  • RESTful형식에 맞춤
  • json, xml 를 쉽게 응답받음

 

2. RestTemplate 의 동작원리

org.springframework.http.client 패키지에 있다. HttpClient는 HTTP를 사용하여 통신하는 범용 라이브러리이고, RestTemplate은 HttpClient 를 추상화(HttpEntity의 json, xml 등)해서 제공해준다. 따라서 내부 통신(HTTP 커넥션)에 있어서는 Apache HttpComponents 를 사용한다. 만약 RestTemplate 가 없었다면, 직접 json, xml 라이브러리를 사용해서 변환해야 했을 것이다.

  1. 어플리케이션이 RestTemplate를 생성하고, URI, HTTP메소드 등의 헤더를 담아 요청한다.
  2. RestTemplate 는 HttpMessageConverter 를 사용하여 requestEntity 를 요청메세지로 변환한다.
  3. RestTemplate 는 ClientHttpRequestFactory 로 부터 ClientHttpRequest 를 가져와서 요청을 보낸다.
  4. ClientHttpRequest 는 요청메세지를 만들어 HTTP 프로토콜을 통해 서버와 통신한다.
  5. RestTemplate 는 ResponseErrorHandler 로 오류를 확인하고 있다면 처리로직을 태운다.
  6. ResponseErrorHandler 는 오류가 있다면 ClientHttpResponse 에서 응답데이터를 가져와서 처리한다.
  7. RestTemplate 는 HttpMessageConverter 를 이용해서 응답메세지를 java object(Class responseType) 로 변환한다.
  8. 어플리케이션에 반환된다.

예제

import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

public class RestTemplateTest {
	public static void main(String[] args) {
		HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
		factory.setReadTimeout(5000); // 읽기시간초과, ms
		factory.setConnectTimeout(3000); // 연결시간초과, ms
		HttpClient httpClient = HttpClientBuilder.create().setMaxConnTotal(100) // connection pool 적용
				.setMaxConnPerRoute(5) // connection pool 적용
				.build();
		factory.setHttpClient(httpClient); // 동기실행에 사용될 HttpClient 세팅
		RestTemplate restTemplate = new RestTemplate(factory);
		String url = "http://testapi.com/search?text=1234";
		Object obj = restTemplate.getForObject("요청할 URI 주소", "응답내용과 자동으로 매핑시킬 java object");
		System.out.println(obj);
	}
}

 

 

1. WebClient이란?

WebClient는 Spring5 에 추가된 인터페이스다. spring5 이전에는 비동기 클라이언트로 AsyncRestTemplate를 사용을 했지만 spring5 부터는 Deprecated 되어 있다. 만약 spring5 이후 버전을 사용한다면 AsyncRestTemplate 보다는 WebClient 사용하는 것을 추천한다. 아직 spring 5.2(현재기준) 에서 AsyncRestTemplate 도 존재하긴 한다.

기본 문법

기본적으로 사용방법은 아주 간단하다. WebClient 인터페이스의 static 메서드인 create()를 사용해서 WebClient 를 생성하면 된다. 한번 살펴보자.

@Test
void test1() {

    WebClient webClient = WebClient.create("http://localhost:8080");
    Mono<String> hello = webClient.get()
            .uri("/sample?name={name}", "wonwoo")
            .retrieve()
            .bodyToMono(String.class);

    StepVerifier.create(hello)
            .expectNext("hello wonwoo!")
            .verifyComplete();
}

@Test
void test2() {

    WebClient webClient = WebClient.create();
    Mono<String> hello = webClient.get()
            .uri("http://localhost:8080/sample?name={name}", "wonwoo")
            .retrieve()
            .bodyToMono(String.class);

    StepVerifier.create(hello)
            .expectNext("hello wonwoo!")
            .verifyComplete();
}

@Test
void test1_3() {

    WebClient webClient = WebClient.create();
    Mono<String> hello = webClient.get()
            .uri("http://localhost:8080/sample?name=wonwoo")
            .retrieve()
            .bodyToMono(String.class);

    StepVerifier.create(hello)
            .expectNext("hello wonwoo!")
            .verifyComplete();
}


@Test
void test1_3() {

    WebClient webClient = WebClient.create("http://localhost:8080");
    Mono<String> hello = webClient.get()
            .uri("/sample?name={name}", Map.of("name", "wonwoo"))
            .retrieve()
            .bodyToMono(String.class);

    StepVerifier.create(hello)
            .expectNext("hello wonwoo!")
            .verifyComplete();
}

@Test
void test1_3() {

    WebClient webClient = WebClient.create("http://localhost:8080");
    Mono<String> hello = webClient.get()
            .uri("/sample?name={name}", "wonwoo")
            .retrieve()
            .bodyToMono(String.class);

    StepVerifier.create(hello)
            .expectNext("hello wonwoo!")
            .verifyComplete();
}

@Test
void test1_3() {

    WebClient webClient = WebClient.create("http://localhost:8080");
    Mono<String> hello = webClient.get()
            .uri(it -> it.path("/sample")
                    .queryParam("name", "wonwoo")
                    .build()
            ).retrieve()
            .bodyToMono(String.class);

    StepVerifier.create(hello)
            .expectNext("hello wonwoo!")
            .verifyComplete();
}

 

'JAVA' 카테고리의 다른 글

java 리스트간 비교, 값 체크  (0) 2021.02.24
Kafka  (0) 2021.02.24
비동기, 동기, 블로킹, 논블로킹  (0) 2021.02.19
JAVA11  (0) 2019.10.04
Oracle JDK 라이센스 전환  (0) 2019.10.04

+ Recent posts