일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 백준
- Servlet
- 인프런
- 스프링 핵심 원리
- 알고리즘
- 스프링
- JDBC
- JPQL
- java
- Proxy
- 김영한
- SpringBoot
- Exception
- Spring Boot
- 그리디
- Greedy
- db
- spring
- Android
- pointcut
- 자바
- QueryDSL
- AOP
- 스프링 핵심 기능
- jpa
- http
- Thymeleaf
- springdatajpa
- transaction
- kotlin
- Today
- Total
목록Proxy (14)
개발자되기 프로젝트
스프링에서 CGLIB는 구체 클래스를 상속 받아서 AOP 프록시를 생성할 때 사용한다. CGLIB는 구체 클래스를 상속 받기 때문에 다음과 같은 문제가 있다. 대상 클래스에 기본 생성자 필수 생성자 2번 호출 문제 final 키워드 클래스, 메서드 사용 불가 1. 대상 클래스에 기본 생성자 필수 CGLIB는 구체 클래스를 상속 받는다. 자바 언어에서 상속을 받으면 자식 클래스의 생성자를 호출할 때 자식 클래스의 생성자에서 부모 클래스의 생성자도 호출해야 한다. (이 부분이 생략되어 있다면 자식 클래스의 생성자 첫줄에 부모 클래스의 기본 생성자를 호출하는 super() 가 자동으로 들어간다.) 이 부분은 자바 문법 규약이다. CGLIB를 사용할 때 CGLIB가 만드는 프록시의 생성자는 우리가 호출하는 것이..
JDK 동적 프록시와 CGLIB를 사용해서 AOP 프록시를 만드는 방법에는 각각 장단점이 있다. JDK 동적 프록시는 인터페이스가 필수이고, 인터페이스를 기반으로 프록시를 생성한다. CGLIB는 구체 클래스를 기반으로 프록시를 생성한다. 물론 인터페이스가 없고 구체 클래스만 있는 경우에는 CGLIB를 사용해야 한다. 그런데 인터페이스가 있는 경우에는 JDK 동적 프록시나 CGLIB 둘중에 하나를 선택할 수 있다. 스프링이 프록시를 만들때 제공하는 ProxyFactory 에 proxyTargetClass 옵션에 따라 둘중 하나를 선택해서 프록시를 만들 수 있다. proxyTargetClass=false --> JDK 동적 프록시를 사용해서 인터페이스 기반 프록시 생성 proxyTargetClass=true..
앞서 생성자 주입이 실패하는 이유는 자기 자신을 생성하면서 주입해야 하기 때문이다. 이 경우 수정자 주입을 사용하거나 지금부터 설명하는 지연 조회를 사용하면 된다. 스프링 빈을 지연해서 조회하면 되는데, ObjectProvider(Provider) , ApplicationContext 를 사용 1. ApplicationContext @Slf4j @Component public class CallServiceV2 { private final ApplicationContext applicationContext; public CallServiceV2(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } p..
1. 스프링은 프록시 방식의 AOP를 사용한다. 따라서 AOP를 적용하려면 항상 프록시를 통해서 대상 객체(Target)을 호출해야 한다. 이렇게 해야 프록시에서 먼저 어드바이스를 호출하고, 이후에 대상 객체를 호출한다. 만약 프록시를 거치지 않고 대상 객체를 직접 호출하게 되면 AOP가 적용되지 않고, 어드바이스도 호출되지 않는다. 2. AOP를 적용하면 스프링은 대상 객체 대신에 프록시를 스프링 빈으로 등록한다. 따라서 스프링은 의존관계 주입시에 항상 프록시 객체를 주입한다. 프록시 객체가 주입되기 때문에 대상 객체를 직접 호출하는 문제는 일반적으로 발생하지 않는다. 하지만 대상 객체의 내부에서 메서드 호출이 발생하면 프록시를 거치지 않고 대상 객체를 직접 호출하는 문제가 발생한다. 3. 내부 호출이..
자동 프록시 생성기( AnnotationAwareAspectJAutoProxyCreator )는 Advisor 를 자동으로 찾아와서 필요한 곳에 프록시를 생성하고 적용해준다고 했다. 자동 프록시 생성기는 여기에 추가로 하나의 역할을 더 하는데, 바로 @Aspect 를 찾아서 이것을 Advisor 로 만들어준다. 쉽게 이야기해서 지금까지 학습한 기능에 @Aspect 를 Advisor 로 변환해서 저장하는 기능도 한다. 그래서 이름 앞에 AnnotationAware (애노테이션을 인식하는)가 붙어 있는 것이다. 1. 자동 프록시 생성기가 하는 일 1) @Aspect 를 보고 어드바이저( Advisor )로 변환해서 저장한다. 2) 어드바이저를 기반으로 프록시를 생성한다 1.1 @Aspect 를 어드바이저로 ..
1. @Aspect 프록시 - 적용 스프링 애플리케이션에 프록시를 적용하려면 포인트컷과 어드바이스로 구성되어 있는 어드바이저 ( Advisor )를 만들어서 스프링 빈으로 등록하면 된다. 그러면 나머지는 앞서 배운 자동 프록시 생성기가 모두 자동으로 처리해준다. 자동 프록시 생성기는 스프링 빈으로 등록된 어드바이저들을 찾고, 스프링 빈들에 자동으로 프록시를 적용해준다. (물론 포인트컷이 매칭되는 경우에 프록시를 생성한다.) 스프링은 @Aspect 애노테이션으로 매우 편리하게 포인트컷과 어드바이스로 구성되어 있는 어드바이저 생성 기능을 지원한다. 지금까지 어드바이저를 직접 만들었던 부분을 @Aspect 애노테이션을 사용해서 만들어보자. 참고 @Aspect 는 관점 지향 프로그래밍(AOP)을 가능하게 하는 ..
1. Application 로딩 로그 EnableWebMvcConfiguration.requestMappingHandlerAdapter() EnableWebMvcConfiguration.requestMappingHandlerAdapter() time=63ms 애플리케이션 서버를 실행해보면, 스프링이 초기화 되면서 기대하지 않은 이러한 로그들이 올라온다. 그 이유는 지금 사용한 포인트컷이 단순히 메서드 이름에 "request*", "order*", "save*" 만 포함되어 있으면 매칭 된다고 판단하기 때문이다. 결국 스프링이 내부에서 사용하는 빈에도 메서드 이름에 request 라는 단어만 들어가 있으면 프록시가 만들어지고 되고, 어드바이스도 적용되는 것이다. 결론적으로 패키지에 메서드 이름까지 함께 지..
빈 후처리기를 사용해서 실제 객체 대신 프록시를 스프링 빈으로 등록해보자. 이렇게 하면 수동으로 등록하는 빈은 물론이고, 컴포넌트 스캔을 사용하는 빈까지 모두 프록시를 적용할 수 있다. 더 나아가서 설정 파일에 있는 수 많은 프록시 생성 코드도 한번에 제거할 수 있다. 1. PackageLogTracePostProcessor @Slf4j public class PackageLogTracePostProcessor implements BeanPostProcessor { //특정 패키지 하위의 빈이 대상 private final String basePackage; private final Advisor advisor; public PackageLogTracePostProcessor(String basePack..