728x90

예제는 깃허브에 있다.

AOP (Aspect Oriented Programming)

AOP는 스프링의 핵심 구성요소중 하나이다.
관점지향 프로그래밍은 프로그램 구조에 대한 또 다른 사고방식을 제공하며
객체 지향 프로그래밍을 보완해준다.

  • OOP의 모듈화 핵심 단위
    • 클래스
  • AOP의 모듈화 단위
    • 관점 (aspect)

AOP는 횡단 관심사의 분리를 허용해주어 모듈성을 높이는 것을 목표로 하는 패러다임이다.
코드 자체를 수정하지 않고 기존 코드에 추가 동작을 추가해서 수행한다.

개념 그리고 용어

  • Aspect
    • 여러 클래스에 중복되어 있는 관심사의 모듈화
    • 대표적인 예로 트랜잭션 관리가 있다.
    • Spring AOP 에서는 @Aspect를 사용한다.
  • JoinPoint
    • 메소드 실행이나 예외 처리와 같은 프로그램 실행중인 지점
    • AOP에서의 JoinPoint는 항상 메소드 실행을 나타냄.
  • Advice
    • 언제 공통 관심 기능을 핵심 로직에 적용할지를 정의
    • around, before, after 등이 있음.
    • AOP 프레임워크는 관점을 인터셉터로 모델링하고 유지한다.
    • 타깃 오브젝트에 종속되지 않는 순수한 부가기능을 담은 오브젝트
  • PointCut
    • Advice가 이 포인트컷 표현식과 연관되고, 일치하는 모든 조인 포인트에서 실행되게 한다.
    • JoinPoint의 상세 스펙을 정의한 것이다.
    • 스프링은 기본적으로 AspectJ의 pointcut 표현식을 사용한다.
  • Advisor
    • PointCutAdvice를 하나씩 가지고 있는 오브젝트
    • 어떤 기능을 어디에 전달할 것인지를 알고있는 가장 기본이 되는 모듈
    • Spring AOP에서만 사용되는 용어

스프링 AOP의 특징

프록시 패턴 기반의 AOP 구현체, 프록시 객체를 사용하는 이유는 여러개의 부가 기능들을 추가하기 위해서 사용한다.
스프링 빈에만 AOP를 적용할 수 있다.
스프링 IoC와 연동해서 중복 코드, 프록시 패턴 구현의 번거로움, 객체간 복잡도 해결을 진행한다.
결국 프록시 패턴, 데코레이터 패턴에 대한 중복도도 제거하려고 나온것이 스프링 AOP라고 생각한다.

스프링 프록시 방식의 AOP 적용

프록시 방식의 AOP를 적용하려면 최소 아래의 네가지 빈을 등록해야 한다.

  • AutoProxyCreator
  • Advice
  • PointCut
  • Advisor

일반 스프링 프레임워크에서는 설정을 해주려면 xml에 여러가지 설정들을 해주어야 하지만,

부트에서는 build.gradle에 의존성 하나만 추가해주면 자동으로 설정이 된다.

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-aop
}

추가적으로 PointCut을 정의할 때에는 위에서 설명했던 것 처럼
AspectJ 표현식을 통해 정의해준다. 자세한건 여기를 통해서 확인할 수 있다.

AOP 어노테이션

모든 어노테이션 뒤에는 AspectJ 표현식을 사용해서 적용할 부분을 정의해준다.

  • @Pointcut
    • AspectJ를 적용할 타겟을 정의해준다.
    • 전체 컨트롤러의 함수대상, 특정 어노테이션을 설정한 함수대상, 특정 메소드 대상 등 적용하기를 원하는 범위를 정의하는 어노테이션
  • @Before
    • 조건 표현식에 정의한 메소드들이 실행되기 전에 수행
  • @AfterReturning
    • 적용된 타깃 메소드가 실행된 후에 수행
  • @Around
    • 타깃 메소드 실행 전, 후 처리 둘다 수행이 가능
    • 사용해줄 때 해당 메소드를 ProceedingJoinPoint로 받아준다.

프록시 팩토리의 기술 선택 방법

  • 대상에 인터페이스가 있으면
    • JDK 동적 프록시, 인터페이스 기반 프록시
  • 대상에 인터페이스가 없으면
    • cglib, 구체 클래스 기반 프록시
  • ProxyFactory의 setProxyTargetClass(true);
    • cglib, 구체클래스 기반 프록시, 인터페이스 여부 상관없음
728x90

'Spring' 카테고리의 다른 글

@ModelAttribute, @RequestBody 커맨드 객체  (3) 2022.09.15
@Valid, @Validated 차이  (0) 2022.08.10
@ExceptionHandler  (0) 2022.08.10
Spring Rest Docs 테스트로 문서화를 해보자!  (0) 2022.08.10
728x90

이진 트리 순회

불과 반년전만 해도 이름만 들었지 마냥 먼곳에 있다고 생각했던 자료구조들이다.
근데 공부하면서 깨닫는 것은 뭐를 알아야 준비를 하고 공부도 하고
재밌게 문제도 풀 수 있다는 것이다. 그것이 바로 코딩테스트 😱
DFS니 BFS니 하려면
일단 스택, 큐, 배열, 재귀에 대해서 알아야된다고 생각했다.
물론 그리고 지금 포스팅하는 이 이진 트리에 대해서도 좀 짚고 넘어가야 한다고 봤다.

이진트리란?

이진트리는 각각의 노드가 아래 자식 노드를 최대 두개를 가진 트리 자료 구조이다.

이진트리 예시

위 이미지는 위키백과 에서 가져와봤다.
깊이(depth)는 3이고 크기는 9인 이진트리이다.

     1
  2     3
4  5   6  7

이런식으로 구성된 트리가 있을 때 전위 표기식으로 순서를 나타내는 알고리즘을 구성해보자

코드

public class Main {
    private static class Node {
        private int value;

        private Node left;
        private Node right;

        public Node(int value) {
            this.value = value;
            left = right = null;
        }
    }

    private static void dfs(Node n) {
        if (n == null) {
            return;
        }

        System.out.print(n.value + " ");
        dfs(n.left);
        dfs(n.right);
    }

}

자기 자신의 노드 그리고 left, right의 자식 노드를 알고있어서 재귀로 다음 노드를 호출하며

null인 경우에는 바로 return을 해주어 바로 다음 로직으로 이동하게끔 구현이 되었다.

전위 순회로 출력하게 되면 1 2 4 5 3 6 7 순서로 나오게 된다.

728x90

'CS > 자료구조' 카테고리의 다른 글

자료구조  (0) 2022.08.10
728x90

@ExceptionHandler

예외 처리기가 어떻게 동작하는지에 대해서 궁금했어서
업무중에 돌려보게 되었다. (예제코드는 다시 작성할 예정)
일단 동작과정은 DB에서 해당 id를 찾아 검색했을 때 없을 경우 예외를 던져주게 하는

예시

간단하게 보면

public class UserService {
    private final UserRepository userRepository;

    public User findById(final int id) {
        return userRepository.findById(id)
                             .orElseThrow(() -> new NotFoundException("해당 유저를 찾을 수 없습니다"));
    }
}

라고 로직을 구성했을 때 이 로직의 예외에 대한 핸들러 동작을 파보게 되었다.
일단 get 메소드로 조회 로직을 수행하고

그 요청을 RequestMappingHandlerAdapter로 위임해서 처리를 요청한다.

그다음 주어진 값들로 컨트롤러에 대한 로직을 처리하는데

InvocableHandlerMethod

다음 그림이 InvocableHandlerMethod 클래스이다.

스크린샷 2022-02-09 오전 11 14 03

이 때, getBridgedMethod().invoke(getBean(), args); 부분이

cglibAopProxy쪽으로 조회 로직을 맡기게 되고 그 곳에서 repository에 대한 동작을 수행하다가
findById에서 못찾았을 경우에 에러를 던지게 된다.
다시 cglibAopProxy에서 요청결과에 대한 에러를 잡아서 다시 처리되는데

이것이 InvocableHandlerMethodcatch로 넘어온다.

catch (InvocationTargetException ex) 이부분에서

RuntimeException의 인자인지를 확인한다.

NotFoundException

이 부분에서 내가 구현한 NotFoundException 의 상속도는

NotFoundException -> NoSuchElementException -> RuntimeException -> Exception 순서기 때문에

instanceof RuntimeException 으로 처리가 되게 된다.

그렇게해서 exception 객체를 담아서 DispatcherServlet 으로 넘겨주게 된다.

DispatcherServlet

이젠 디스패쳐 서블릿이 받은 에러를 처리해줄 누군가를 찾기 시작하는데

스크린샷 2022-02-09 오전 11 18 55

HandlerExceptionResolverComposite

스크린샷 2022-02-09 오전 11 19 56

이 두 개중 HandlerExceptionResolverComposite 로 처리를 진행해준다.

그렇게 해서 resolveException 메소드를 실행해주는데

다음 이미지를 보게되면 resolvers에 3개가 들어있게 된다.

스크린샷 2022-02-09 오전 11 20 44

그 리졸버들이 바로 HandlerExceptionResolver 들을 구현한것들

스크린샷 2022-02-09 오전 11 22 39

그중에서도 나는 ResponseStatusException을 날려준게 아니기 때문에

그중에서 최종적으로 HandlerExceptionResolver 인터페이스 구현체인

ExceptionHandlerExceptionResolver, ResponseStatusExceptionResolver, DefaultHandlerExceptionResolver

세개를 가지고 for문을 돌게 된다

InvocableTargetException 이라는 객체의 target

즉, 대상이 어떤 Exception이냐에 따라서 Exception 에맞는 @ExceptionHandler로 파싱되어 커스텀된 응답으로 나가게 된다.

마무리

똑같은 로직 이라고 가정했을때 미묘하게 최적화를 하고싶다? 한다면

HandlerExceptionResolver 리스트의 맨앞인 ExceptionHandlerExceptionResolver를 사용 그러니까

커스텀으로 @ExceptionHandler 를 만들어 쓰는것이 ResponseStatusException 을 던지거나, @ResponseStatus 을 사용하는것보다

빠를 수 있겠다.

728x90

'Spring' 카테고리의 다른 글

@Valid, @Validated 차이  (0) 2022.08.10
AOP  (0) 2022.08.10
Spring Rest Docs 테스트로 문서화를 해보자!  (0) 2022.08.10
Service Layer에 대한 생각  (0) 2022.08.10
728x90

선택 정렬 (Select Sort)

선택 정렬은 현재 위치에 들어갈 데이터를 찾아 선택하는 알고리즘이다.
오름차순을 기준으로 정렬한다.

개념

제자리 정렬의 알고리즘 중 하나이다.
정렬 되지 않은 입력된 배열 외에 다른 메모리를 사용하지 않는다.
해당하는 n번째에 넣을 정렬된 원소 자리는 이미 정해져있고,
어떤 값을 넣을지를 선택하는 알고리즘이다.

동작 과정

  1. 주어진 배열에서 최솟값을 찾는다.
  2. 그 최솟값을 배열의 맨 앞의 수와 자리를 교체해준다.
  3. 맨 처음 값을 뺀 나머지 배열로부터 최솟값을 찾는다.
  4. 교체한 다음 맨 앞의 배열과 값을 바꿔준다.
  5. 이 과정을 정렬이 완료될 때까지 계속 반복한다.

스크린샷 2022-02-07 오후 10 19 41

보기 좋은 예시 이미지를 가져와봤다.
이제 그러면 구현을 해보도록 하자.

Select Sort 구현

n 길이를 가진 배열을 생성하고 다음줄에 n개의 숫자를 입력받아 선택정렬 한다.

public class SelectionSort {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine()); //길이가 n
        StringTokenizer st = new StringTokenizer(br.readLine());

        int[] arr = new int[n]; //n개의 숫자를 넣을 배열

        for (int i = 0; i < n; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }

        final int[] results = solution(arr);

        for (int result : results) {
            System.out.print(result);
        }
    }

    private static int[] solution(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }

            //최소값과 해당 반복 index의 맨 앞자리와 치환
            int temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
        return arr;
    }
}

결론

이런 사소한 지식이라도 안적어두면 까먹고 또 기억이 안나는것 같다.
위의 예시도 ide도움 없이 손코딩으로 포스팅을 올려보는데 더 상기되서 까먹지 않을것 같다.
계속 까먹기 때문에 이렇게 기록으로 남겨두는것이 좋을듯 하다. 😎

728x90

'CS > 알고리즘' 카테고리의 다른 글

에라토스테네스의 체  (0) 2022.08.09
728x90

자료구조

자료 구조의 사전적인 의미는,
효율적인 접근 및 수정을 가능케하는 자료의 조직, 관리, 저장을 의미한다.
그래서 이 자료구조는,
데이터들의 값 모임, 데이터간 관계 들을 의미한다.
이 사전적 의미를 보니까 알고리즘과 뗄래야 뗄 수가 없는거 같다.
결국 이 선택에 따라 효율적으로 알고리즘을 설계를 할 수 있으니까 말이다.

들어가며

이 자료구조들은 당연히 여러 가지가 있으며, 각각의 자료구조는 각자의 연산과 목적에 맞춰져 있다.

단순히 알고리즘 문제들만 풀 때 자료구조를 선택한다? 답은 NO

어떠한 기능을 설계함에 있어 자료구조를 선택하는 것은 필수일 것이다.
자꾸 예를 알고리즘으로 들어서 그렇지만, 이만큼 알고리즘과 뗄래야 뗄 수가 없다는것.
자료구조가 명확해지면, 그에 따라오는 알고리즘이 반드시 필요한게 있을 거라고 본다.

종류

자료의 특성, 크기, 사용법, 연산에 따라 여러가지 종류가 있다.
크게 단순 구조, 선형 구조, 비선형 구조, 파일 구조로 나눌 수 있다.

스크린샷 2022-02-01 오후 9 42 40

단순 구조

  • True/False, 정수, 실수, 문자 및 문자열과 같이 컴퓨터가 기본적으로 제공하는 자료형

선형 구조

  • Array(배열)
    • 가장 일반적인 구조
    • 메모리 상에 같은 타입의 자료가 연속적으로 저장
    • 자료값을 나타내는 가장 작은 단위
  • LinkedList
    • 노드를 하나의 단위로 한다.
    • 노드는 자료와 다음 노드를 가리키는 참조값으로 구성
    • 점 조직 같은 느낌
  • Stack
    • 후입선출(Last-In-First-Out)
    • 먼저 저장된 것이 마지막에 나오게 되는구조
    • 자료의 나열 순서를 바꾸고 싶다면 스택에 넣었다가 꺼내면 역순으로 변경된다.
  • Queue
    • 선입선출(First-In-First-Out)
    • 먼저 저장된 것이 먼저 나오게 되는 구조
  • Deque
    • 양쪽에서 넣기 빼기를 할 수 있는 구조

비 선형 구조

  • Graph
    • 꼭짓점과 꼭짓점을 잇는 변으로 구성된다.
  • Tree
    • 뿌리와 뿌리 또는 다른 꼭짓점을 하나의 부모로 갖는 꼭짓점들로 이루어진 구조
    • 부모와 자식의 관계는 변으로 표현

파일 구조

하드디스크 같은 보조 기억장치에 저장되는 파일에 대한 자료구조
메모리에 한번에 로드할 수 없는 대용량의 자료
파일 구성 방식에 따라 순차, 색인, 직접으로 나뉘게 된다.

728x90

'CS > 자료구조' 카테고리의 다른 글

이진트리  (0) 2022.08.10
728x90

728x90

'Spring' 카테고리의 다른 글

AOP  (0) 2022.08.10
@ExceptionHandler  (0) 2022.08.10
Service Layer에 대한 생각  (0) 2022.08.10
Validaion  (0) 2022.08.09

+ Recent posts