본문 바로가기

분류 전체보기

(318)
[Spring] 스프링 AOP 구현 목차프로젝트 생성예제 프로젝트 만들기스프링 AOP 구현1 - 시작스프링 AOP 구현2 - 포인트컷 분리스프링 AOP 구현3 - 어드바이스 추가스프링 AOP 구현4 - 포인트컷 참조스프링 AOP 구현5 - 어드바이스 순서스프링 AOP 구현6 - 어드바이스 종류 프로젝트 생성  AOP 기능을 사용하기 위해서 다음을 build.gradle 에 직접 추가implementation 'org.springframework.boot:spring-boot-starter-aop'build.gradle 에 테스트 코드에서도 lombok을 사용할 수 있도록 다음 코드를 추가//테스트에서 lombok 사용testCompileOnly 'org.projectlombok:lombok'testAnnotationProcessor 'or..
[Spring] 스프링 AOP 개념 목차AOP 소개 - 핵심 기능과 부가 기능 AOP 소개 - AspectAOP 적용 방식 AOP 용어 정리 AOP 소개 - 핵심 기능과 부가 기능애플리케이션 로직은 크게 핵심 기능과 부가 기능으로 나눌 수 있다.핵심 기능은 해당 객체가 제공하는 고유의 기능이다.예를 들어서 OrderService 의 핵심 기능은 주문 로직이다.부가 기능은 핵심 기능을 보조하기 위해 제공되는 기능이다. 예를 들어서 로그 추적 로직, 트랜잭션 기능이 있다. 이러한 부가 기능은 단독으로 사용되지 않고, 핵심 기능과 함께 사용된다. 예를 들어서 로그 추적 기능은 어떤 핵심 기능이 호출되었는지 로그를 남기기 위해 사용한다. 그러니까 부가 기능은 이름 그대로 핵심 기능을 보조하기 위해 존재한다.  주문 로직을 실행하기 직전에 로그 추..
[Spring] @Aspect 프록시 목차@Aspect 프록시 - 적용 @Aspect 프록시 - 설명 @Aspect 프록시 - 적용스프링 애플리케이션에 프록시를 적용하려면 포인트컷과 어드바이스로 구성되어 있는 어드바이저( Advisor )를 만들어서 스프링 빈으로 등록하면 된다. 그러면 나머지는 자동 프록시 생성기가 모두 자동으로 처리해준다. 자동 프록시 생성기는 스프링 빈으로 등록된 어드바이저들을 찾고, 스프링 빈들에 자동으로 프록시를 적용해준다. (포인트컷이 매칭되는 경우에 프록시를 생성한다.)스프링은 @Aspect 애노테이션으로 매우 편리하게 포인트컷과 어드바이스로 구성되어 있는 어드바이저 생성 기능을 지원한다.지금까지 어드바이저를 직접 만들었던 부분을 @Aspect 애노테이션을 사용해서 만들어보자.참고@Aspect 는 관점 지향 프로..
[Spring] 빈 후처리기 목차빈 후처리기 - 소개빈 후처리기 - 예제 코드1빈 후처리기 - 예제 코드2빈 후처리기 - 적용스프링이 제공하는 빈 후처리기1스프링이 제공하는 빈 후처리기2하나의 프록시, 여러 Advisor 적용 빈 후처리기 - 소개 @Bean 이나 컴포넌트 스캔으로 스프링 빈을 등록하면, 스프링은 대상 객체를 생성하고 스프링 컨테이너 내부의 빈 저장소에 등록한다. 그리고 이후에는 스프링 컨테이너를 통해 등록한 스프링 빈을 조회해서 사용하면 된다.빈 후처리기 - BeanPostProcessor 스프링이 빈 저장소에 등록할 목적으로 생성한 객체를 빈 저장소에 등록하기 직전에 조작하고 싶다면 빈 후처리기를 사용하면 된다. 빈 포스트 프로세서( BeanPostProcessor )는 번역하면 빈 후처리기인데, 이름 그대로 빈..
[Spring] 스프링이 지원하는 프록시(ProxyFactory) 목차프록시 팩토리 - 소개프록시 팩토리 - 예제 코드1프록시 팩토리 - 예제 코드2포인트컷, 어드바이스, 어드바이저 - 소개예제 코드1 - 어드바이저예제 코드2 - 직접 만든 포인트컷예제 코드3 - 스프링이 제공하는 포인트컷예제 코드4 - 여러 어드바이저 함께 적용프록시 팩토리 - 적용 프록시 팩토리 - 소개앞서 마지막에 설명했던 동적 프록시를 사용할 때 문제점을 다시 확인해보자.문제점인터페이스가 있는 경우에는 JDK 동적 프록시를 적용하고, 그렇지 않은 경우에는 CGLIB를 적용하려면 어떻게 해야할까?두 기술을 함께 사용할 때 부가 기능을 제공하기 위해 JDK 동적 프록시가 제공하는 InvocationHandler 와 CGLIB가 제공하는 MethodInterceptor 를 각각 중복으로 만들어서 관리..
[Spring] 동적 프록시 기술(JDK 동적 프록시, CGLIB) 목차리플렉션JDK 동적 프록시 - 소개JDK 동적 프록시 - 예제 코드JDK 동적 프록시 - 적용1JDK 동적 프록시 - 적용2CGLIB - 소개CGLIB - 예제 코드 리플렉션지금까지 프록시를 사용해서 기존 코드를 변경하지 않고, 로그 추적기라는 부가 기능을 적용할 수 있었다. 그런데 문제는 대상 클래스 수 만큼 로그 추적을 위한 프록시 클래스를 만들어야 한다는 점이다. 로그 추적을 위한 프록시 클래스들의 소스코드는 거의 같은 모양을 하고 있다.자바가 기본으로 제공하는 JDK 동적 프록시 기술이나 CGLIB 같은 프록시 생성 오픈소스 기술을 활용하면 프록시 객체를 동적으로 만들어낼 수 있다. 쉽게 이야기해서 프록시 클래스를 지금처럼 계속 만들지 않아도 된다는 것이다. 프록시를 적용할 코드를 하나만 만들..
[디자인 패턴] 프록시 패턴 목차예제 프로젝트프록시, 프록시 패턴, 데코레이터 패턴 - 소개프록시 패턴 - 예제 코드1프록시 패턴 - 예제 코드2데코레이터 패턴 - 예제 코드1데코레이터 패턴 - 예제 코드2데코레이터 패턴 - 예제 코드3프록시 패턴과 데코레이터 패턴 정리인터페이스 기반 프록시 - 적용구체 클래스 기반 프록시 - 예제1구체 클래스 기반 프록시 - 예제2구체 클래스 기반 프록시 - 적용인터페이스 기반 프록시와 클래스 기반 프록시 예제 프로젝트 다양한 상황에서 프록시 사용법을 이해하기 위해 다음과 같은 기준으로 기본 예제 프로젝트를 만들었다.예제는 크게 3가지 상황으로 만든다.v1 - 인터페이스와 구현 클래스 - 스프링 빈으로 수동 등록v2 - 인터페이스 없는 구체 클래스 - 스프링 빈으로 수동 등록v3 - 컴포넌트 스캔..
[디자인 패턴] 템플릿 콜백 패턴 목차템플릿 콜백 패턴 - 시작템플릿 콜백 패턴 - 예제템플릿 콜백 패턴 - 적용 템플릿 메서드 패턴 - 시작ContextV2 는 변하지 않는 템플릿 역할을 한다. /** * 전략을 파라미터로 전달 받는 방식 */@Slf4jpublic class ContextV2 { public void execute(Strategy strategy) { long startTime = System.currentTimeMillis(); // 비즈니스 로직 실행 strategy.call(); // 위임 // 비즈니스 로직 종료 long endTime = System.currentTimeMillis(); long resultTime = endTim..
[디자인 패턴] 전략 패턴 목차전략 패턴 - 시작전략 패턴 - 예제1전략 패턴 - 예제2전략 패턴 - 예제3 전략 패턴 - 시작전략 패턴의 이해를 돕기 위해 템플릿 메서드 패턴에서 만들었던 동일한 예제를 사용해보자. ContextV1Test@Slf4jpublic class ContextV1Test { @Test void strategyV0() { logic1(); logic2(); } private void logic1() { long startTime = System.currentTimeMillis(); // 비즈니스 로직 실행 log.info("비즈니스 로직1 실행"); // 비즈니스 로직 종료 long endTime ..
[디자인 패턴] 템플릿 메서드 패턴 목차템플릿 메서드 패턴 - 시작템플릿 메서드 패턴 - 예제1템플릿 메서드 패턴 - 예제2템플릿 메서드 패턴 - 예제3템플릿 메서드 패턴 - 적용1템플릿 메서드 패턴 - 적용2템플릿 메서드 패턴 - 정의 템플릿 메서드 패턴 - 시작지금까지 로그 추적기를 열심히 잘 만들었다. 요구사항도 만족하고, 파라미터를 넘기는 불편함을 제거하기 위해 쓰레드 로컬도 도입했다. 그런데 로그 추적기를 막상 프로젝트에 도입하려고 하니 개발자들의 반대의 목소리가 높다. 로그 추적기 도입 전과 도입 후의 코드를 비교해보자. 로그 추적기 도입 전 - V0 코드//OrderControllerV0 코드@GetMapping("/v0/request")public String request(String itemId) { orderSer..