분류 전체보기 1341

Ch06. 스프링이 지원하는 프록시 - 프록시 팩토리(적용)

어드 바이스 생성 public class LogTraceAdvice implements MethodInterceptor { private final LogTrace logTrace; public LogTraceAdvice(LogTrace logTrace) { this.logTrace = logTrace; } @Override public Object invoke(MethodInvocation invocation) throws Throwable { TraceStatus status = null; try { Method method = invocation.getMethod(); String message = method.getDeclaringClass().getSimpleName() + "." + metho..

Ch06. 스프링이 지원하는 프록시 - 어드바이저(예제)

어드바이저는 하나의 포인트 컷과 하나의 어드바이스를 가지고 있다. 프록시 팩토리를 통해 프록시를 생성할 때 어드바이저를 제공하면 어디에 어떤 기능을 제공할지 알 수 있다. @Test public void advisorTest1() { ServiceInterface target = new ServiceImpl(); ProxyFactory proxyFactory = new ProxyFactory(target); DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(Pointcut.TRUE, new TimeAdvice());//항상 참인 Advisor proxyFactory.addAdvisor(advisor); //이전에 advice 만 하게 된다면 내부에..

Ch06. 스프링이 지원하는 프록시 - 포인트컷, 어드바이스, 어드바이저( 소개)

포인트 컷( Pointcut ): 어디에 부가 기능을 적용할지, 어디에 부가 기능을 적용하지 않을지 판단하는 필터링 로직이다. 주로 클래스와 메서드 이름으로 필터링한다. 이름 그대로 어떤 포인트(Point)에 기능을 적용할지 하지 않을지 잘라서(cut) 구분하는 것이다. 어드바이스( Advice ): 이전에 본 것 처럼 프록시가 호출하는 부가 기능이다. 단순하게 프록시 로직이라 생각하면 된다. 어드바이저( Advisor ): 단순하게 하나의 포인트컷과 하나의 어드바이스를 가지고 있는 것이다. 쉽게 이야기해서 포인트 컷 1 + 어드바이스 1이다 쉽게 기억하기 조언( Advice )을 어디( Pointcut )에 할 것인가? 조언자( Advisor )는 어디( Pointcut )에 조언( Advice )을 ..

Ch06. 스프링이 지원하는 프록시 - 프록시 팩토리(예제)

Advice 만들기 Advice는 프록시에 적용하는 부가 기능 로직이다. 이것은 JDK 동적 프록시가 제공하는 InvocationHandler와 CGLIB가 제공하는 MethodInterceptor의 개념과 유사한다. 둘을 개념적으로 추상화한 것이다. 프록시 팩토리를 사용하면 둘 대신에 Advice를 사용하면 된다. Advice를 만드는 방법은 여러 가지가 있지만, 기본적인 방법은 다음 인터페이스를 구현하면 된다. @Slf4j public class TimeAdvice implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { log.info("TimeProxy 실행"..

Ch06. 스프링이 지원하는 프록시 - 프록시 팩토리(소개)

인터페이스가 있는 경우에는 JDK 동적 프록시를 적용하고, 그렇지 않은 경우에는 CGLIB를 적용하려면 어떻게 해야 할까? 스프링은 유사한 구체적인 기술들이 있을 때, 그것들을 통합해서 일관성 있게 접근할 수 있고, 더욱 편리하게 사용할 수 있는 추상화된 기술을 제공한다. 스프링은 동적 프록시를 통합해서 편리하게 만들어주는 프록시 팩토리( ProxyFactory )라는 기능을 제공한다. 이전에는 상황에 따라서 JDK 동적 프록시를 사용하거나 CGLIB를 사용해야 했다면, 이제는 이 프록시 팩토리 하나로 편리하게 동적 프록시를 생성할 수 있다. 프록시 팩토리는 인터페이스가 있으면 JDK 동적 프록시를 사용하고, 구체 클래스만 있다면 CGLIB를 사용한다. 그리고 이 설정을 변경할 수도 있다. 두 기술을 함..

Ch05. 동적 프록시 기술 - CGLIB

CGLIB는 바이트코드를 조작해서 동적으로 클래스를 생성하는 기술을 제공하는 라이브러리이다 . CGLIB를 사용하면 인터페이스가 없어도 구체 클래스만 가지고 동적 프록시를 만들어낼 수 있다. CGLIB는 원래는 외부 라이브러리인데, 스프링 프레임워크가 스프링 내부 소스 코드에 포함했다. 따라서 스프링을 사용한다면 별도의 외부 라이브러리를 추가하지 않아도 사용할 수 있다 예제 코드 작성 인터페이스와 구현이 있는 서비스 클래스 public interface ServiceInterface { void save(); void find(); } @Slf4j public class ServiceImpl implements ServiceInterface{ @Override public void save() { log..

Ch05. 동적 프록시 기술 - JDK 동적 프록시(적용)

InvocationHandler @Slf4j public class LogTraceBasicHandler implements InvocationHandler { private final Object target; private final LogTrace logTrace; public LogTraceBasicHandler(Object target, LogTrace logTrace) { this.target = target; this.logTrace = logTrace; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { TraceStatus status = null; try { Strin..

Ch05. 동적 프록시 기술 - JDK 동적 프록시

동적 프록시 기술을 사용하면 개발자가 직접 프록시 클래스를 만들지 않아도 된다. 이름 그대로 프록시 객체를 동적으로 런타임에 개발자 대신 만들어준다. 그리고 동적 프록시에 원하는 실행 로직을 지정할 수 있다 주의 JDK 동적 프록시는 인터페이스를 기반으로 프록시를 동적으로 만들어준다. 따라서 인터페이스가 필수이다. AInterface public interface AInterface { String call(); } AImpl @Slf4j public class AImpl implements AInterface{ @Override public String call() { log.info("A 호출"); return "A"; } } BInterface public interface BInterface { ..

Ch05. 동적 프록시 기술 - 리플렉션

문제는 대상 클래스 수만큼 로그 추적을 위한 프록시 클래스를 만들어야 한다는 점이다. 로그 추적을 위한 프록시 클래스들의 소스코드는 거의 같은 모양을 하고 있다. 자바가 기본으로 제공하는 JDK 동적 프록시 기술이나 CGLIB 같은 프록시 생성 오픈소스 기술을 활용하면 프록시 객체를 동적으로 만들어낼 수 있다. 쉽게 이야기해서 프록시 클래스를 지금처럼 계속 만들지 않아도 된다는 것이다. 프록시를 적용할 코드를 하나만 만들어두고 동적 프록시 기술을 사용해서 프록시 객체를 찍어내면 된다 JDK 동적 프록시를 이해하기 위해서는 먼저 자바의 리플렉션 기술을 이해해야 한다. 리플렉션 기술을 사용하면 클래스나 메서드의 메타정보를 동적으로 획득하고, 코드도 동적으로 호출할 수 있다 리플렉션 사용 X 테스트 @Test..

Ch04. 프록시 패턴과 데코레이터 패턴 - 인터페이스 기반 프록시와 클래스 기반 프록시 정리

프록시 프록시를 사용한 덕분에 원본 코드를 전혀 변경하지 않고, V1, V2 애플리케이션에 LogTrace 기능을 적용할 수 있었다 인터페이스 기반 프록시 vs 클래스 기반 프록시 인터페이스가 없어도 클래스 기반으로 프록시를 생성할 수 있다. 클래스 기반 프록시는 해당 클래스에만 적용할 수 있다. 인터페이스 기반 프록시는 인터페이스만 같으면 모든 곳에 적용할 수 있다. 클래스 기반 프록시는 상속을 사용하기 때문에 몇가지 제약이 있다. 부모 클래스의 생성자를 호출해야 한다.(앞서 본 예제) 클래스에 final 키워드가 붙으면 상속이 불가능하다. 메서드에 final 키워드가 붙으면 해당 메서드를 오버라이딩 할 수 없다 이렇게 보면 인터페이스 기반의 프록시가 더 좋아보인다. 맞다. 인터페이스 기반의 프록시는 ..