현재까지는 OOP를 이용하여 공부를 했지만, OOP는 응집도가 낮다는 단점이 있어서 응집도를 높이기 위해 AOP를 공부해야 한다.
(IoC로 결합도를 낮췄으니 AOP로 응집도를 높여보자 !)
OOP와 AOP의 차이점
OOP
- AOP 이전에는 일일히 로그를 직접 추가했었다. 따라서 단순 페이지 요청 조차도 로그가 찍혔다. 메소드 호출을 하기 때문에 느리다.
AOP
- 이제는 AOP를 사용하므로 Service를 사용하는 건에 대해서만 AOP를 수행하기 때문에, 로그가 찍히지 않는다. 따라서 메소드 호출을 하지 않기 때문에 빠르다.
AOP란 ?
AOP는 관점 지향 프로그래밍으로, 관점을 기준으로 다양한 기능을 분리하여 보는 프로그래밍을 말한다.
* 응집도를 높일 수 있는 구조
기본적으로 구조는 아래와 같다.

현재까지는 로그를 이렇게 직접 작성해야 했다면, AOP를 사용하게 되면 1번으로 적힌 라인은 삭제해도 무방하다. 그 이유는 직접 로그를 작성해주기 때문이다.
흐름을 분석한 주석을 다시 정리하자면,
1) (개발자용) 로그
2) 권한 확인 단계 : 보안, 인증, 허가, ...
3) 비즈니스 메소드(CRUD, 핵심 로직, 핵심 관심) 실행
4) 트랜잭션, 보안 관제 로그, ...
여기서 사용자의 요청이 달라졌을 때 1, 2, 4번은 계속 반복되고 3번만 달라진다.
우리(개발자)는 무언가 반복되면 모듈화를 하고 싶어하는데, AOP에서는 "관심 분리(Separation of Concerns)"라고 한다.
이와 같이 계속 반복되는 1, 2, 4번 로직을 '공통 로직(횡단 로직)'이라고 말하고, 3번과 같이 사용자의 요청에 따라 계속 변경되는 것을 '핵심 로직, 핵심 관심, 비즈니스 메소드, CRUD' 라고 한다.
먼저 AOP를 사용하기 위해서는 [.jar] 파일이 필요하다. 즉, pom.xml 에 추가해야한다. 추가해야할 코드는 아래와 같다.
pom.xml
<!-- AOP -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.8</version>
</dependency>
다음으로 applicationContext.xml에 aop 네임스페이스를 추가해야 한다.

applicationContext.xml에 aop를 추가해야 하는 이유
AOP 설정 완료되는 시점이 사용자가 *.do 를 하는 시점보다 더 먼저 실행되어야 하기 때문이다.
AOP를 들어가기 전에 용어 정리를 한번 하자면
- Advice (어드바이스)
횡단 관심, 공통 로직을 말한다.
동작 시점을 설정할 수 있다. --> 비즈니스 메소드 기준으로 전 / 후 / 함께 / .. 진행 가능하다.
오늘 실습은 LogAdvice를 해볼 예정
- PointCut (포인트컷)
핵심 관심, 핵심 로직, 비즈니스 메소드, CRUD
공통 로직인 Advice가 결합될 대상을 의미한다.
포인트컷 기본적인 형식
<aop:pointcut expression="execution(OUTPUT FUNCNAME(INPUT))" id="" />
- Aspect 애스팩트(Advisor 어드바이저)
포인트컷 + 어드바이스
포인트컷과 어드바이스의 "결합" 그 자체를 의미한다.
애스펙트 설정에 따라 위빙 처리된다.
- Weaving 위빙
포인트컷으로 지정한 핵심 관심 메소드가 호출될 때, 어드바이스에 해당하는 횡단 관심 메소드가 삽입되는 과정 그 자체를 의미한다.
(스프링은 런타임 위빙 처리 방식을 사용함)
- JoinPoint 조인
포인트컷 후보
포인트컷이 될 수 있는 대상들
핵심 관심들
applicationContext.xml 선언 방법
<bean id="logAdvice" class="com.spring.biz.common.LogAdvice" />
<aop:config>
<!-- 나 포인트컷 설정할거야 핵심로직으로 얘를 준비했어 -->
<aop:pointcut expression="execution(* com.spring.biz..*Impl.*(..))" id="aPointCut"/>
<aop:aspect ref="logAdvice"> <!-- logAdvice랑 결합시켜줘 -->
<aop:before method="printLog" pointcut-ref="aPointCut"/>
<!-- aPointCut 수행 전에 printLog 메소드 호출해줘 -->
</aop:aspect>
</aop:config>
위의 코드는 비즈니스 메소드 호출 전에 로그를 출력할 때 사용하는 방법이고, 비즈니스 메소드 수행 후에 로그를 출력하고 싶다면 'before'을 'after'로 변경할 수 있다.
<aop:after method="printLog" pointcut-ref="aPointCut"/>
포인트 컷은 여러개 등록할 수 있다. CUD는 DB에 변화를 줄 수 있기 때문에 데이터에 대한 확실한 검증이 필요하다. 그래서 상대적으로 보안, 유효성 검사, 트랜잭션 등이 많이 필요하다.
하지만 R은 DB에 변화를 주지 않으므로 보려는 데이터에 접근 할 수 있는 권한이 있는지만 확인하면 된다. 따라서 상대적으로 공통 로직이 적게 필요하다.
따라서 일부 포인트컷에만 어드바이스(횡단 관심, 공통 로직)가 동작할 수 있도록 설정할 수 있다.
<!-- 이와 같이 두개로 나누어 호출할 수 있음 -->
<aop:pointcut expression="execution(* com.spring.biz..*Impl.select*(..))" id="bPointCut"/>
<aop:before method="printLog" pointcut-ref="bPointCut"/>
명령어 정리
1. aop:after >> 비즈니스 메소드 후에 어드바이스가 호출됨
2. aop:after-returning >> 비즈니스 메소드 OUTPUT 반환 후에 어드바이스가 호출됨
3. aop:after_throwing >> 비즈니스 메소드 오류 발생 후에 어드바이스가 호출됨
4. aop:around >> 비즈니스 메소드 수행하기 전 후에 호출됨
--> * around가 진행되는 동안에 비즈니스 메소드가 내부에서 호출되는 것임
5. aop:before >> 비즈니스 메소드 전에 어드바이스가 호출됨
'Spring' 카테고리의 다른 글
| [Spring] Spring JDBC (JDBCTemplate) (1) | 2023.08.16 |
|---|---|
| [Spring] AOP (AfterReturning & AfterThrowing) (0) | 2023.08.14 |
| [Spring] 2 - Layerd 아키텍처 스타일 (0) | 2023.08.11 |
| [Spring] Command 객체 VIEW에서 사용하기 (0) | 2023.08.10 |
| [Spring] @Component를 상속받은 어노테이션 (0) | 2023.08.10 |