분류 전체보기

    [스프링 핵심 원리 고급편]

    인터페이스 기반 프록시 장점 * 원본 코드 수정 없이 기능 추가 가능 * 구조 깔끔함 단점 * 너무 많은 프록시 클래스 생성됨 * 인터페이스 없는 클래스에 적용 불가 * 캐스팅 관련 단점 있음 (나중에 수업 예정) 구체클래스 기반 프록시 장점 * 원본 코드 수정 없이 기능 추가 가능 * 인터페이스 없이도 구현 가능 단점 * 너무 많은 프록시 클래스가 생성됨 * 클래스와 메서드에 final 키워드가 붙은 경우 오버라이드 불가능 결론: 원본코드 수정 없이 기능 추가했지만, 대상 클래스만 다르고 로직은 같은데도 여러 프록시 클래스를 만들어 로직을 복붙했음 동적프록시로 이 단점 해결할 것

    [스프링 핵심 원리 고급편] 프록시 패턴과 데코레이터 패턴

    템플릿 메서드 패턴, 전략 패턴, 템플릿 콜백 패턴 ==> 클라이언트 코드를 수정하는 단점 # 프록시(Proxy)란? 클라이언트의 요청을 서버 대신 처리해주는 대리자 클라이언트가 사용하는 서버 객체를 프록시 객체로 변경해도 클라이언트 코드를 변경하지 않고 동작할 수 있어야 한다. # 프록시의 주요 기능 1. 접근 제어 2. 부가 기능 추가 위 의도(intent)에 따라 프록시는 두 가지 패턴으로 불린다. ## 1. 프록시 패턴 - 접근제어 - 권한에 따른 접근 차단 - 캐싱 - 지연 로딩 ## 2. 데코레이터 패턴 - 부가 기능 추가 - 원래 서버가 제공하는 기능에 더해서 부가 기능을 수행한다. - 예) 요청 값이나, 응답 값을 중간에 변형한다. - 예) 실행 시간을 측정해서 추가 로그를 남긴다. ## ..

    [스프링 핵심 원리 고급편] 전략 패턴

    복습) 템플릿 메서드 패턴 abstract 클래스에 공통로직을 구현하고, 비즈니스 로직은 클래스를 상속하여 구현 -> 비즈니스 클래스가 결국 공통로직을 가지고 있는 형태임, 부모의 수정에 영향을 받을 수 있음 번외) 익명클래스에서 람다변경 -> 인터페이스에 메서드 하나만 있을 때 가능 ContextV1 contextV1 = new ContextV1(new Strategy() { @Override public void call() { log.info("비즈니스 로직1 실행"); } }); ContextV1 contextV1 = new ContextV1(() -> log.info("비즈니스 로직1 실행")); 되돌아보는 우리의 목적 - 공통 로직을 여러 메서드에 추가하고 싶음 - 공통 로직을 추가할 때 기존..

    [스프링 핵심 원리 고급편] 템플릿 메서드 패턴

    템플릿 메서드 패턴 : 변하는 것과 변하지 않는 것을 분리 예상) 로직을 따로 분리하기? 공통기능 로직을 가진 클래스를 extends를 해서 override함 -> 리턴값을 맞출 수 없을 것 같음 변하지 않는 부분은 부모클래스에 정의, 변하는 부분은 자식에서 오버라이드 템플릿 메서드 패턴의 단점 클래스를 계속 만들어야 함 -> 익명 내부클래스 를 만들면 된다. 예상) 리턴값을 커스텀할 수 없음 리턴값 설정 제네릭을 통해서 해결가능함 AbstractTemplate 로 만들어두면, 클래스를 만들 때 type을 넣어줄 수 있음 메서드의 반환값을 T로 두면 반환값 세팅 가능 -> 제네릭 설정은 클래스단위인데, execute는 메서드 단위임 두 개 이상의 메서드가 있고 각각 다른 타입을 리턴하고 싶으면 어떡함? ..

    [스프링 핵심원리 고급편] 예제 만들기 & ThreadLocal

    ## 요구사항 0. 다음 흐름의 api를 구현한다. client 요청 -> controller -> service -> repository -> service -> controller -> 응답 1. 각 계층에서 로그를 찍는다. 2. 각 계층에서 로직을 마칠 때 찍는 로그에는 소요 시간도 추가한다. 3. 어느 뎁스인지 UI로 표시한다. 4. 각 요청의 ID를 부과하여 같이 출력한다. [fbda3e10] OrderController.request() [fbda3e10] |--->OrderService.request() [fbda3e10] | |--->OrderRepository.request() [fbda3e10] | |

    그냥 궁금한 점) 전통적 MVC 방식과 RestAPI 방식의 차이

    ## 전통적 MVC 방식과 RestAPI 방식의 차이 @RestController vs @Controller @RestController == @Controller + @ResponseBody RestController 애노테이션에 들어가보면 ResponseBody 애노테이션이 붙어있다. 컨트롤러에 붙이지 않고 이렇게 메서드에 달아서 사용할 수도 있음 (물론 용도에 따라 rest/일반 컨트롤러를 분리하는 것을 권장) ``` @Controller @RequiredArgsConstructor public class UserController { private final UserService userService; @GetMapping(value = "/users") public @ResponseBody Re..

    [초보 웹 개발자를 위한 스프링5 프로그래밍 입문] 08. DB연동

    ## JDBC 단점 보완 커넥션을 여닫고 에러핸들링을 하는 등 JDBC에서 반복적인 코드를 줄이기 위해 템플릿 메서드 패턴과 전략 패턴을 함께 사용해 구현한 것이 JdbcTemplate이다. 스프링은 거기에 @Transactional 애노테이션을 제공하여 트랜잭션 관리를 쉽게 했다. 예제 코드 작성을 위해서는 세 개의 디펜던시를 추가하면 된다. 1. spring-jdbc: JdbcTemplate 등 JDBC 연동에 필요한 기능 제공 2. tomcat-jdbc: DB 커넥션풀 기능 제공 3. mysql-connector-java: MySQL 연결에 필요한 JDBC드라이버 제공 아래 코드로 DataSource를 빈으로 등록할 수 있다. tomcat의 데이터소스는 커넥션풀 기능을 제공하는 데이터소스 구현 클래..

    [초보 웹 개발자를 위한 스프링5 프로그래밍 입문] 07. AOP 프로그래밍

    ## 설정법 spring-context, aspectjweaver 모듈 의존성 추가 ``` public class ReculsiveCalculator implements Calculator { @Override public long factorial(long num) { if (num = 0) return 1; else return num * factorial(num - 1); } } ``` 코드가 있다고 할 때 이 함수의 실행시간을 알아내려면 어떻게 해야 하는가? 함수 앞뒤에 모두 시간을 출력하는 라인을 추가해야 한다. 수정사항이 있을 때마다 반복해야한다. 딱 한번만 수정하기 위해 프록시의 개념이 등장한다. ``` public class TimeReculsiveCalculator implements C..