개발이 좋아서/Spring이 좋아서

    AOP - 실전 예제

    @Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface Trace {}@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface Retry { int value() default 3;}@Slf4j@Aspectpublic class TraceAspect { @Before("@annotation(hello.aop.exam.annotation.Trace)") public void doTrace(JoinPoint joinPoint) { Object[] args = joinPoint.getArgs(); ..

    AOP - 포인트컷

    포인트컷 지시자 - 포인트컷 표현식은 execution 같은 포인트컷 지시자(Pointcut Designator)로 시작한다. 줄여서 PCD라 한다.포인트컷 지시자의 종류execution : 메소드 실행 조인 포인트를 매칭한다. 스프링 AOP에서 가장 많이 사용하고, 기능도 복잡하 다.within : 특정 타입 내의 조인 포인트를 매칭한다.args : 인자가 주어진 타입의 인스턴스인 조인 포인트this : 스프링 빈 객체(스프링 AOP 프록시)를 대상으로 하는 조인 포인트target : Target 객체(스프링 AOP 프록시가 가리키는 실제 대상)를 대상으로 하는 조인 포인트@target : 실행 객체의 클래스에 주어진 타입의 애노테이션이 있는 조인 포인트@within : 주어진 애노테이션이 있는 타입 ..

    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(); }}   @Pointcut@Slf4j@Aspectpublic class AspectV2 { //hello.aop.order 패키지와 하위 패키지 @Pointcut("execution(* hello.aop....

    AOP - 개념

    적용방식컴파일 시점클래스 로딩 시점런타임 시점(프록시) 컴파일 시점 단점 - 컴파일 시점에 부가 기능을 적용하려면 특별한 컴파일러도 필요하고 복잡하다. (AspectJ가 제공하는 특별한 컴파일러를 사용해야 한다.) 클래스 로딩 시점 단점 - 로드 타임 위빙은 자바를 실행할 때 특별한 옵션('java -javaagent')을 통해 클래스 로더 조작기를 지정해야 하는데, 이 부분이 번거롭고 운영하기 어렵다. 특징- 컴파일 시점: 실제 대상 코드에 애스팩트를 통한 부가 기능 호출 코드가 포함된다. AspectJ를 직접 사용해야 한 다.- 클래스 로딩 시점: 실제 대상 코드에 애스팩트를 통한 부가 기능 호출 코드가 포함된다. AspectJ를 직접 사용해야 한다.- 런타임 시점: 실제 대상 코드는 그대로 유지된다..

    빈 후처리기

    public class BeanPostProcessorTest { @Test void basicConfig() { ApplicationContext ac = new AnnotationConfigApplicationContext(BeanPostProcessorConfig.class); //beanA 이름으로 B 객체가 빈으로 등록된다. B b = ac.getBean("beanA", B.class); b.helloB(); //A는 빈으로 등록되지 않는다. assertThrows(NoSuchBeanDefinitionException.class, () -> ac.getBean(A.class)); } @Slf4j ..

    포인트컷, 어드바이스, 어드바이저

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

    프록시 팩토리

    public interface ServiceInterface { void save(); void find();}@Slf4jpublic class ServiceImpl implements ServiceInterface { @Override public void save() { log.info("save 호출"); } @Override public void find() { log.info("find 호출"); }}@Slf4jpublic class ConcreteService { public void call() { log.info("ConcreteService 호출"); }}@Slf4jpublic class TimeA..

    JDK 동적 프록시, CGLIB

    JDK 동적 프록시public interface AInterface { String call();}public interface BInterface { String call();}@Slf4jpublic class AImpl implements AInterface { @Override public String call() { log.info("A 호출"); return "a"; }}@Slf4jpublic class BImpl implements BInterface { @Override public String call() { log.info("B 호출"); return "b"; }}@Slf4jpublic class..

    구체 클래스 기반 프록시

    @Slf4jpublic class ConcreteLogic { public String operation() { log.info("ConcreteLogic 실행"); return "data"; }}public class ConcreteClient { private ConcreteLogic concreteLogic; public ConcreteClient(ConcreteLogic concreteLogic) { this.concreteLogic = concreteLogic; } public void execute() { concreteLogic.operation(); }}@Slf4jpublic class TimeProxy..

    프록시 - 프록시 패턴(기능 추가)

    public interface Component { String operation();}@Slf4jpublic class RealComponent implements Component { @Override public String operation() { log.info("RealComponent 실행"); return "data"; }}@Slf4jpublic class DecoratorPatternClient { private Component component; public DecoratorPatternClient(Component component) { this.component = component; } public ..