Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- java
- 스프링 핵심 기능
- 자바
- db
- Exception
- 인프런
- QueryDSL
- 스프링
- kotlin
- 백준
- 김영한
- Greedy
- springdatajpa
- jpa
- JPQL
- pointcut
- 그리디
- 알고리즘
- http
- AOP
- Thymeleaf
- Android
- SpringBoot
- transaction
- Proxy
- 스프링 핵심 원리
- JDBC
- Servlet
- spring
- Spring Boot
Archives
- Today
- Total
개발자되기 프로젝트
[AOP] AOP 적용 방식 본문
- AOP를 사용하면 핵심 기능과 부가 기능이 코드상 완전히 분리되어서 관리된다.
- 그렇다면 AOP를 사용할 때 부가 기능 로직은 어떤 방식으로 실제 로직에 추가될 수 있을까?????
- 3가지 방법
컴파일 시점
클래스 로딩 시점
런타임 시점(프록시) --> 지금까지 한거
1. 컴파일 시점 : AspectJ 사용
- .java 소스 코드를 컴파일러를 사용해서 .class 를 만드는 시점에 부가 기능 로직을 추가할 수 있다.
- 이때는 AspectJ가 제공하는 특별한 컴파일러를 사용해야 한다.
- 컴파일 된 .class 를 디컴파일 해보면 애스펙트 관련 호출 코드가 들어간다.
- 한 마디로 부가 기능 코드가 핵심 기능이 있는 컴파일된 코드 주변에 실제로 붙어 버린다고 생각하면 된다.
- AspectJ 컴파일러는 Aspect를 확인해서 해당 클래스가 적용 대상인지 먼저 확인하고,
- 적용 대상인 경우에 부가 기능 로직을 적용한다.
- 참고로 이렇게 원본 로직에 부가 기능 로직이 추가되는 것을 위빙(Weaving)이라 한다.
- Weaving: 옷감을 짜다. 직조하다. 애스펙트와 실제 코드를 연결해서 붙이는 것
- 단점
컴파일 시점에 부가 기능을 적용하려면 특별한 컴파일러도 필요하고 복잡하다.
2. 클래스 로딩 시점: AspectJ 사용
- 자바를 실행하면 자바 언어는 .class 파일을 JVM 내부의 클래스 로더에 보관한다.
- 이때 중간에서 .class 파일을 조작한 다음 JVM에 올릴 수 있다.
- 자바 언어는 .class 를 JVM에 저장하기 전에 조작할 수 있는 기능을 제공한다.
- 궁금한 분은 java Instrumentation를 검색해보자. 참고로 수 많은 모니터링 툴들이 이 방식을 사용한다.
- 이 시점에 애스펙트를 적용하는 것을 로드 타임 위빙이라 한다.
- 단점
로드 타임 위빙은 자바를 실행할 때 특별한 옵션( java -javaagent )을 통해
클래스 로더 조작기를 지정해야 하는데, 이 부분이 번거롭고 운영하기 어렵다.
3. 런타임 시점
- 런타임 시점은 컴파일도 다 끝나고, 클래스 로더에 클래스도 다 올라가서 이미 자바가 실행되고 난 다음.
- 자바의 메인( main ) 메서드가 이미 실행된 다음이다.
- 따라서 자바 언어가 제공하는 범위 안에서 부가 기능을 적용해야 한다.
- 스프링과 같은 컨테이너의 도움을 받고 프록시와 DI, 빈 포스트 프로세서 같은 개념들을 총 동원해야 한다.
- 이렇게 하면 최종적으로 프록시를 통해 스프링 빈에 부가 기능을 적용할 수 있다.
- 지금까지 우리가 학습한 것이 바로 프록시 방식의 AOP이다.
- 프록시를 사용하기 때문에 AOP 기능에 일부 제약이 있다.
- 하지만 특별한 컴파일러나, 자바를 실행할 때 복잡한 옵션과 클래스 로더 조작기를 설정하지 않아도 된다.
- 스프링만 있으면 얼마든지 AOP를 적용할 수 있다.
4. 세 가지 방식의 차이
- 컴파일 시점
실제 대상 코드에 애스팩트를 통한 부가 기능 호출 코드가 포함된다. AspectJ를 직접 사용해야 한다. - 클래스 로딩 시점
실제 대상 코드에 애스팩트를 통한 부가 기능 호출 코드가 포함된다. AspectJ를 직접 사용해야 한다. - 런타임 시점
실제 대상 코드는 그대로 유지된다. 대신에 프록시를 통해 부가 기능이 적용된다.
따라서 항상 프록시를 통해야 부가 기능을 사용할 수 있다. 스프링 AOP는 이 방식을 사용한다.
5. AOP 적용 위치
AOP는 지금까지 학습한 메서드 실행 위치 뿐만 아니라 다음과 같은 다양한 위치에 적용할 수 있다.
- 적용 가능 지점(조인 포인트)
생성자, 필드 값 접근, static 메서드 접근, 메서드 실행
이렇게 AOP를 적용할 수 있는 지점을 조인 포인트(Join point)라 한다. - AspectJ를 사용해서 컴파일 시점과 클래스 로딩 시점에 적용하는 AOP는
바이트코드를 실제 조작하기 때문에 해당 기능을 모든 지점에 다 적용할 수 있다. - 그런데 프록시 방식을 사용하는 스프링 AOP는 메서드 실행 지점에만 AOP를 적용할 수 있다.
프록시는 메서드 오버라이딩 개념으로 동작한다.- 따라서 생성자나 static 메서드, 필드 값 접근에는 프록시 개념이 적용될 수 없다.
- 프록시를 사용하는 스프링 AOP의 조인 포인트는 메서드 실행으로 제한된다.
- 프록시 방식을 사용하는 스프링 AOP는 스프링 컨테이너가 관리할 수 있는 스프링 빈에만 AOP를 적용할
수 있다. - 즉 스프링 빈으로 등록해야 스프링 AOP 적용 가능
- 참고
스프링은 AspectJ의 문법을 차용하고 프록시 방식의 AOP를 적용한다.
AspectJ를 직접 사용하는 것이 아니다. - 중요
스프링이 제공하는 AOP는 프록시를 사용한다. 따라서 프록시를 통해 메서드를 실행하는 시점에만 AOP가 적용된다. AspectJ를 사용하면 앞서 설명한 것 처럼 더 복잡하고 더 다양한 기능을 사용할 수 있다.
그렇다면 스프링 AOP 보다는 더 기능이 많은 AspectJ를 직접 사용해서 AOP를 적용하는 것이 더 좋지 않음???
AspectJ를 사용하려면 자바 관련 설정(특별한 컴파일러, AspectJ 전용 문법, 자바 실행 옵션) 복잡하다.
반면에 스프링 AOP는 별도의 추가 자바 설정 없이 스프링만 있으면 편리하게 AOP 를 사용할 수 있다.
실무에서는 스프링이 제공하는 AOP 기능만 사용해도 대부문의 문제를 해결할 수 있다.
'인프런 > [인프런] 스프링 핵심 원리 - 고급' 카테고리의 다른 글
[스프링AOP] 프로젝트 생성 (0) | 2022.01.05 |
---|---|
[AOP] AOP 용어 정리 (0) | 2022.01.05 |
[AOP] Aspect (0) | 2022.01.05 |
[AOP] 핵심 기능과 부가 기능 (0) | 2022.01.05 |
[@AspectAOP] @Aspect Proxy (0) | 2022.01.05 |
Comments