스프링 입문 - AOP 적용
AOP 적용
- AOP : Aspect Oriented Programming
- 공통 관심 사항(cross-cutting concern) vs 핵심 관심 사항(core concern) 분리
좌측처럼 분산되어 있는 공통 관심 사항인 시간 측정 로직을
우측 처럼 한곳에 모으고, 내가 원하는 곳에 공통 관심 사항을 적용한다는 개념이 AOP이다.
AOP 적용 방법을 알아보자.
우선, hellospring패키지의 하위에 aop라는 이름으로 패키지를 생성했다
그리고 aop패키지 안에, TimeTraceAop라는 이름으로 클래스를 생성했다.
그리고, Aop는 @Asepect 라는 애너테이션을 적어줘야 한다.
코드는 이렇게 작성해 주었다.
그리고 작성한 Aop클래스인 TimeTraceAop를 스프링빈으로 등록해줘야 한다.
컴포넌트 스캔 방식을 이용하려면,
이렇게 @Component 애너테이션을 작성해줘도 되고,
아니면, 스프링빈에 등록해줘도 된다.
"이것을 AOP로 걸어서 사용하는구나!" 라고 인지하기 쉽도록,
AOP 같은 경우에는, 스프링 빈에 등록하는 방식을 선호한다.
하지만, 예제에서는 컴포넌트 스캔방식을 사용하도록 하겠다.
그리고 추가적으로 @Around 애너테이션을 TimeTraceAop 클래스 내부에 적어줘야 하는데,
@Around("execution(* hello.hellospring..*(..))")
실행하는 패키지명..그밑에있는 클래스명..*(파라미터타입..등등))
해서 원하는 조건을 넣을 수 있다.
이 코드는 hello.hellospring패키지 하위에는 다 적용해! 라는 뜻이다.
이제, 전시간에 MemberService클래스에 작성 해두었던 실행시간출력 관련 코드들을 이렇게 지워주자.
방금 AOP를 작성했기 때문에 지워도 된다.
그리고 이제 서버를 돌려서 확인해보자.
서버를 돌리고 회원 목록을 조회하고 로그를 확인해보자.
START를 해서 MemberController, MemberService, JpaRepository 각각의 실행시간이 잘 찍혔다.
이러면, 어디서 병목이 있는지, 어디서 밀리는지 바로 찾을 수 있을 것이다.
@Around, joinPoint 등으로 원하는 것들을 조작해서 사용할 수 있다.
이런식으로 제공되는 기술이 AOP이다.
해결
- 회원가입, 회원 조회등 핵심 관심사항과 시간을 측정하는 공통 관심 사항을 분리한다.
- 시간을 측정하는 로직을 별도의 공통 로직으로 만들었다.
- 핵심 관심 사항을 깔끔하게 유지할 수 있다.
- 변경이 필요하면 이 로직만 변경하면 된다.
- 원하는 적용 대상을 선택할 수 있다.
스프링의 AOP 동작 방식
AOP를 적용하기 전에는,
컨트롤러에서 서비스를 호출할 때, 그냥 의존관계를 통해 호출을 했다.
그런데, AOP를 적용을 하고, 어디에 적용할 건지 지정을 하면,
지정된 서비스에 대해 가짜 서비스를 만든다.
예를 들어, AOP를 적용하면서, memberService에 적용할 것라고 지정을 했으면,
가짜 memberService를 만든다. 그것을 프록시라고 한다.
그러면서 스프링 컨테이너는 어떻게 동작하냐면,
스프링이 올라와서 스프링컨테이너에 스프링빈을 등록할 때,
진짜 스프링빈 말고, 가짜 스프링빈을 앞에 세워 놓는다.
이 가짜 스프링 빈이 끝나면(joinPoint.proceed()하면), 그때 진짜 스프링빈을 호출해준다.
그래서, 컨트롤러가 호출하는 것은 진짜 멤버서비스가 아니라, 프록시라는 기술로 발생하는 가짜 멤버서비스이다.
실제로 Proxy가 주입되는지 콘솔에 출력해서 확인해 볼 수 있다.
MemberController를 보면, memberService가 인젝션되는데,
System.out.println("memberService = " + memberService.getClass());
이때 getClass()를 살짝 찍어보면 된다.
서버를 돌려서 로그를 확인해보면,
MemberService로 끝나는게 아니라 $$EnhancerBySpringCGLIB$$accf7887 라는 것을 볼 수 있다.
EnhancerBySpringCGLIB를 볼 수 있는데,
CGLIB라는 것은, MemberService를 가지고 복제를해서 코드를 조작하는 기술이다. 이러한 기술이 적용된 것이다.
그래서 AOP가 적용이 되면, 스프링 컨테이너가 "어? 너 MemberService에 AOP가 적용이 되야하네?" 라고 하며
프록시를 생성해서 앞에 세우는 것이다.
그러고나서, 프록시를 통해 AOP가 다 실행이 되고, jointPoint.proceed() 하면 그때, 이제 진짜 MemberService가 호출이 되는 방식이다.
좌측 그림은 AOP 적용전이고,
우측 그림은 AOP의 타깃을 MemberController, MemberService, MemberRepository로 다 설정했을때의 그림이다.
'Spring' 카테고리의 다른 글
스프링 기본 - 비즈니스 요구사항과 설계 (0) | 2022.05.24 |
---|---|
스프링 기본 - 객체 지향 설계와 스프링 / 프로젝트 생성 (0) | 2022.05.24 |
스프링 입문 - AOP가 필요한 상황 (0) | 2022.05.23 |
스프링 입문 - 스프링 데이터 JPA (0) | 2022.05.23 |
스프링 입문 - JPA (0) | 2022.05.22 |
댓글
이 글 공유하기
다른 글
-
스프링 기본 - 비즈니스 요구사항과 설계
스프링 기본 - 비즈니스 요구사항과 설계
2022.05.24 -
스프링 기본 - 객체 지향 설계와 스프링 / 프로젝트 생성
스프링 기본 - 객체 지향 설계와 스프링 / 프로젝트 생성
2022.05.24 -
스프링 입문 - AOP가 필요한 상황
스프링 입문 - AOP가 필요한 상황
2022.05.23 -
스프링 입문 - 스프링 데이터 JPA
스프링 입문 - 스프링 데이터 JPA
2022.05.23