Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
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
more
Archives
Today
Total
관리 메뉴

forDevLife

[TIL]9/15 - AOP 본문

각종 회고

[TIL]9/15 - AOP

JH_Lucid 2021. 9. 29. 15:07
AOP 용어

아래 용어들은 Spring에서만 사용되는 용어들이 아닌 AOP 프레임워크 전체에서 사용되는 공용어입니다.
타겟 (Target)
부가기능을 부여할 대상을 얘기합니다.
여기선 핵심기능을 담당하는 getBoards 혹은 getUsers를 하는 Service 들을 얘기합니다.

애스펙트 (Aspect)
객체지향 모듈을 오프젝트라 부르는것과 비슷하게 부가기능 모듈을 애스펙트라고 부르며, 핵심기능에 부가되어 의미를 갖는 특별한 모듈이라 생각하시면 됩니다.
애스펙트는 부가될 기능을 정의한 어드바이스와 어드바이스를 어디에 적용할지를 결정하는 포인트컷을 함께 갖고 있습니다.
참고로 AOP(Aspect Oriented Programming)라는 뜻 자체가 어플리케이션의 핵심적인 기능에서 부가적인 기능을 분리해서 애스팩트라는 독특한 모듈로 만들어서 설계하고 개발하는 방법을 얘기합니다.

어드바이스 (Advice)
실질적으로 부가기능을 담은 구현체를 얘기합니다.
어드바이스의 경우 타겟 오프젝트에 종속되지 않기 때문에 순수하게 부가기능에만 집중할 수 있습니다.
어드바이스는 애스펙트가 '무엇'을 '언제' 할지를 정의하고 있습니다.

포인트컷 (PointCut)
부가기능이 적용될 대상(메소드)를 선정하는 방법을 얘기합니다.
즉, 어드바이스를 적용할 조인포인트를 선별하는 기능을 정의한 모듈을 애기합니다.

조인포인트 (JoinPoint)
어드바이스가 적용될 수 있는 위치를 얘기합니다.
다른 AOP 프레임워크와 달리 Spring에서는 메소드 조인포인트만 제공하고 있습니다.
(그래서 여러 책이나 문서에서 조인포인트에 대해 생략하기도 합니다. 무조건 메소드 단위로만 지정하기 때문입니다.)
따라서 Spring 프레임워크 내에서 조인포인트라 하면 메소드를 가리킨다고 생각하셔도 됩니다.
타 프레임워크에서는 예외 발생할 경우, 필드값이 수정될 경우 등도 지원하고 있습니다.

프록시 (Proxy)
타겟을 감싸서 타겟의 요청을 대신 받아주는 랩핑(Wrapping) 오브젝트입니다.
호출자 (클라이언트)에서 타겟을 호출하게 되면 타겟이 아닌 타겟을 감싸고 있는 프록시가 호출되어, 타겟 메소드 실행전에 선처리, 타겟 메소드 실행 후, 후처리를 실행시키도록 구성되어있습니다.

 

(AOP에서 프록시는 호출을 가로챈 후, 어드바이스에 등록된 기능을 수행 후 타겟 메소드를 호출합니다.)


인트로덕션 (Introduction)
타겟 클래스에 코드 변경없이 신규 메소드나 멤버변수를 추가하는 기능을 얘기합니다.
자세한 설명은 자바지기님의 포스팅 참고

위빙 (Weaving)
지정된 객체에 애스팩트를 적용해서 새로운 프록시 객체를 생성하는 과정을 얘기합니다.
예를 들면 A라는 객체에 트랜잭션 애스팩트가 지정되어 있다면, A라는 객체가 실행되기전 커넥션을 오픈하고 실행이 끝나면 커넥션을 종료하는 기능이 추가된 프록시 객체가 생성되고, 이 프록시 객체가 앞으로 A 객체가 호출되는 시점에서 사용됩니다. 이때의 프록시객체가 생성되는 과정을 위빙이라 생각하시면 됩니다.
컴파일 타임, 클래스로드 타임, 런타임과 같은 시점에서 실행되지만, Spring AOP는 런타임에서 프록시 객체가 생성 됩니다.

 

 

출처 : https://jojoldu.tistory.com/71?category=635883 

 

AOP 정리 (3)

AOP란? Spring의 핵심 개념중 하나인 DI가 애플리케이션 모듈들 간의 결합도를 낮춰준다면, AOP는 애플리케이션 전체에 걸쳐 사용되는 기능을 재사용하도록 지원하는 것입니다. AOP (Aspect-Oriented Progra

jojoldu.tistory.com

 

< UserService 내의 update2 메서드 >

    @Override
    public void update2(User user, Long id) throws Exception {
        userRepository.save(user);
    }

 

< update2 메서드를 대상으로 Aspect 생성 및 실행 - 파라미터 추출>

//    @Around("execution(* com.blogcode.user.UserService.*(..))")
    @Around("execution(* com.blogcode.user.UserService.update2(..))")
    public Object updateUser2(ProceedingJoinPoint pjp) {
        Object result = null;
        try {
            Object[] args = pjp.getArgs();
            if(args.length != 0) {
                historyRepository.save(new History((Long) args[1]));
            }
            result = pjp.proceed();
        } catch (Throwable throwable) {
            System.out.println("exception! ");
        }
        return result;
    }
  • 파라미터가 없는 조인포인트(여기에서는 update2 메서드)의 경우, update2()로는 인식을 못하고 (..)를 써줘야 한다.
  • 조인포인트로부터 aspect(여기에서는 updateUser2 메서드)가 파라미터를 추출하여 historyRepository에 별도로 save를 하는 추가 기능을 수행한다.

 

 

다음 내용을 공부하다가 AOP가 뭔지 몰라서 학습한 것!

 

< 바깥 메서드 >

    @GetMapping("/em/{id}")
//    @Transactional
    public void findMember5(@PathVariable("id") Long id) {

        Member member1 = memberRepository.findById(id).get();
        System.out.println("member1 : " + member1);

        testComponent.capsule(id);

    }
  • findById에 내부적으로 @Transactional이 적용되어 있다.
  • testComponent.capsule(외부 클래스)에도 @Transactional(propagation = Propagation.REQUIRES_NEW)를 통해 새로운 트랜잭션이 시작되도록 걸어놨다.
Comments