스프링 AOP - 포인트컷포인트컷 지시자AspectJ는 포인트컷을 편리하게 표현하기 위해 특별한 표현식을 제공한다.ex) @Pointcut("execution(* hello.aop.order..*(..))")포인트컷 표현식 = AspectJ가 제공하는 포인트컷 표현식 포인트컷 지시자(PCD) : 포인트컷 표현식에서 시작 부분을 의미포인트컷 지시자 종류execution : 메소드 실행 조인 포인트를 매칭한다. (가장 많이 사용하며 기능이 복잡)within : 특정 타입내의 조인 포인트를 매칭한다.args : 인자가 주어진 타입의 인스턴스 조인 포인트this : 스프링 빈 객체(프록시)를 대상으로 하는 조인 포인트target : Target 객체(원본 객체)를 대상으로 하는 조인 포인트@target : 실행..
스프링 AOP스프링 AOP 구현@Slf4j@Aspectpublic class AspectV1 { @Around("execution(* hello.aop.order..*(..))") public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable { log.info("[log] {}", joinPoint.getSignature()); //join point 시그니처 return joinPoint.proceed(); }}@Aspect를 사용해 AOP 구현@Around 어노테이션 값은 포인트컷이 된다.AspectJ 포인트컷 표현식 사용"execution ~ " : hello.aop.order 패키지 및 하위 패키..
스프링 AOPAOP 소개 - 핵심 기능과 부가 기능애플리케이션 로직은 핵심 기능과 부가 기능으로 나눌 수 있다.핵심 기능 : 해당 객체가 제공하는 고유 기능이다.ex) 주문 로직 기능부가 기능 : 단독으로 사용되지 않고 핵심 기능을 보조하기 위해 제공되는 기능이다.ex) 트랜잭션 기능, 로그 추적 기능 여러 곳에서 공통으로 사용하는 부가 기능의 경우 횡단 관심사(cross-cutting concerns)가 된다. 부가 기능 적용 시 반복, 중복 코드, 수정으로 많은 문제가 발생한다.AOP 소개 - AspectAspect : 핵심 기능과 부가 기능을 분리해서 한 곳에서 관리하도록 하고 부가 기능과 해당 부가 기능을 어디에 적용할지 정의한 것@Aspect, 스프링이 제공하는 Advisor도 하나의 Aspec..
@Aspect AOP@Aspect 프록시 - 적용스프링 애플리케이션에 프록시 적용 시 어드바이저(포인트컷+어드바이스)를 만들어서 스프링 빈으로 등록하면 된다.나머지는 자동 프록시 생성기(빈 후처리기)가 스프링 빈으로 등록된 어드바이저들을 찾고 스프링 빈들에 자동으로 프록시를 적용함으로 모두 처리해준다. 스프링은 @Aspect 어노테이션으로 매우 편리하게 어드바이져 생성 기능을 지원한다.@Aspect는 관점 지향 프로그래밍(AOP)을 가능하게 하는 AspectJ 프로젝트에서 제공하는 어노테이션이다. @Slf4j@Aspectpublic class LogTraceAspect { private final LogTrace logTrace; public LogTraceAspect(LogTrace logT..
빈 후처리기빈 후처리기 - 소개@Bean이나 컴포넌트 스캔으로 스프링 빈을 등록하는 경우스프링은 대상 객체를 생성스프링 컨테이너 내부의 빈 저장소에 등록이후 스프링 컨테이너를 통해 등록된 스프링 빈을 조회해서 사용빈 후처리기 - BeanPostProcessor스프링이 빈 저장소에 등록할 목적으로 생성한 객체를 빈 저장소에 등록하기 직전 조작하기 위한 것이다.빈을 생성한 후 무언가를 처리하기 위한 용도로 사용한다.객체를 조작할 수도 있고, 완전히 다른 객체로 바꿔치기 하는 것도 가능하다. 빈 후처리기 과정생성 : 스프링 빈 대상이 되는 객체를 생성한다.(@Bean, 컴포넌트 스캔 포함)전달 : 생성된 객체를 빈 저장소에 등록하기 전 빈 후처리기에 전달한다.후 처리 작업 : 빈 후처리기는 전달된 스프링 빈 ..
프록시 팩토리이전에는 상황에 따라서 인터페이스가 있으면 JDK 동적 프록시를 사용하고 구체 클래스의 경우 CGLIB를 사용했다면 프록시 팩토리 하나로 동적 프록시를 생성할 수 있다.프록시 팩토리 : 스프링에서 제공하는 동적 프록시를 통합해서 편리하게 만들어주는 기능이다.동작 방식 - 인터페이스가 있으면 JDK 동적 프록시를 사용, 구체 클래스만 있으면 CGLIB를 사용한다.부가 기능 적용 시 Advice를 만들면 InvocationHandler나 MethodInterceptor를 신경쓰지않아도 된다.프록시 팩토리를 사용하면 Advice를 호출하는 전용 (스프링에서 제공) InvocationHandler, MethodInterceptor를 내부에서 사용 Advice 동작 흐름클라이언트가 프록시 팩토리에게 ..
동적 프록시 기술리플렉션프록시를 사용하기 위해서 프록시 클래스를 별도로 만들지 않더라도 자바에서 제공하는 JDK 동적 프록시 기술이나 CGLIB같은 프록시 생성 오픈소스 기술을 활용하면 프록시 객체를 동적으로 만들어낼 수 있다. 리플렉션 기술 : 클래스나 메소드의 메타정보를 동적으로 획득하고 코드도 동적으로 호출할 수 있는 기술이다. @Slf4jpublic class ReflectionTest { @Test public void reflection0() { Hello target = new Hello(); //공통 로직1 시작 log.info("start"); String result1 = target.callA(); //호출하는 메소드가 다름..
예제 프로젝트 만들기예제 프로젝트 종류v1 - 인터페이스와 구현 클래스 (스프링 빈 수동 등록)v2 - 인터페이스 없는 구체 클래스 (스프링 빈 수동 등록)v3 - 컴포넌트 스캔 (스프링 빈 자동 등록)실무에서 스프링 빈으로 등록할 클래스는 인터페이스가 있는 경우도 없는 경우도 있다.스프링 빈으로 직접 등록하는 경우도, 컴포넌트 스캔으로 자동 등록하는 경우도 있다.예제 프로젝트 만들기 - v1public interface OrderRepositoryV1 { void save(String itemId);}public class OrderRepositoryV1Impl implements OrderRepositoryV1 { @Override public void save(String itemI..
템플릿 메소드 패턴 Template Method Pattern이전 로그 추적기 예제를 보면 V0는 실제 처리해야할 핵심 기능만 있는 반면에 V3는 핵심 기능보다 로그 출력을 위한 부가 기능이 더 많고 복잡하다. 핵심 기능 vs 부가 기능핵심 기능 : 해당 객체가 제공하는 고유의 기능이다.ex) OrderService 클래스의 orderItem()의 핵심 기능은 주문 데이터를 저장하기 위해 레포지토리를 호출하는 orderRepository.save(itemId)가 핵심 기능이다.부가 기능 : 핵심 기능을 보조하기 위해 제공되는 기능이다.부가 기능은 단독으로 사용되지 않고 핵심 기능과 함께 사용된다.ex) 로그 추적기, 트랜잭션 기능 좋은 설계는 변하는 것과 변하지 않는 것을 분리하는 것이다.변하는 것과 변..
필드 동기화필드 동기화 - 개발, 적용이전 예제에서는 로그 출력 시 필요한 트랜잭션ID와 level을 동기화하기 위해서 TraceId를 파라미터로 넘겨서 구현했다. public interface LogTrace { TraceStatus begin(String message); void end(TraceStatus status); void exception(TraceStatus status, Exception e);}새 로그 추적기 인터페이스 예제 @Slf4jpublic class FieldLogTrace implements LogTrace { private static final String START_PREFIX = "-->"; private static final Strin..