인생 디벨로퍼

AOP 기본 연습 (1) 본문

JAVA Spring

AOP 기본 연습 (1)

뫄뫙뫄 2023. 3. 14. 15:12
728x90
반응형

 

@Hello 를 v2 에만 붙임 (깃발 꽂기)

hello 어노테이션을 만들어 주고

@Pointcut 으로 경로 별칭을 만들어준다 (포인터를 컷해준다..)

 

  • @Aspect : AOP에서 관심사를 구현하는데 사용, 일반적인 자바 클래스를 관심사로 사용할 수 있으며, 메서드 앞에 @Before, @After, @Around와 같은 다양한 어노테이션을 붙여 해당 메서드가 언제 실행되어야 하는지를 지정

 

  • @Component : 자동으로 빈으로 등록되며,  세부적인 어노테이션들을 포함하고 있습니다.
    • @Controller: 스프링 MVC에서 컨트롤러로 사용되는 클래스에 지정합니다.
    • @Service: 비즈니스 로직을 담당하는 클래스에 지정합니다.
    • @Repository: 데이터 접근 객체(DAO)로 사용되는 클래스에 지정합니다.

 

@Before  메소드 실행 전 어노테이션이 실행된다

v1 실행시, 아무 일도 일어나지 않음

System.out.println("안녕안녕"); 이 실행!

@After 를 사용해서, 메서드 실행 후 

getMapping() 또는  hello() 가 실행 되도록 했다.

v1 은 @After 이 걸린 "헉헉" 을

v2는 @Before 과 @After 모두 리턴했다.

 


@Around

사실 @Before 와 @After 은 거의 사용하지 않는다고 한다.

우리는 앞으로 

@Around 를 사용하려 한다.

파라메터 크기와 입력값을 알수 있다.

 


코드 정리

package shop.mtcoding.aopstudy.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import shop.mtcoding.aopstudy.handler.aop.Hello;

@RestController
public class HelloController {

    @GetMapping("/v1")
    public String v1() {
        return "v1";
    }

    @Hello
    @GetMapping("v2")
    public String v2(String username) {
        return "v2";
    }

    @Hello
    @GetMapping("v3")
    public String v3(String username) {
        return "v3";
    }

}
package shop.mtcoding.aopstudy.handler.aop;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Hello {

}
  • @Target(ElementType.METHOD) : 어노테이션이 적용될 수 있는 자바 요소의 종류를 지정
  • @Retention(RetentionPolicy.RUNTIME) : 어노테이션의 유지(retention) 정책(policy)을 지정RetentionPolicy.RUNTIME : 어노테이션을 런타임 시점까지 유지
package shop.mtcoding.aopstudy.handler;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class HelloAdvice {
    /*
     * shop.mtcoding.aopstudy.handler.aop.Hello -> 깃발 이름
     */
    @Pointcut("@annotation(shop.mtcoding.aopstudy.handler.aop.Hello)") // 깃발에 별칭 달기 (깃발 이름을 줄여줌)
    public void hello() {
    }

    @Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")
    public void getMapping() {
    }

    // @Before("hello()")
    // public void helloAdvice() {
    // System.out.println("안녕안녕");
    // }

    // @After("getMapping() || hello()")
    // public void getAdvice() {
    // System.out.println("헉헉");
    // }

    // @Around("hello()")
    // public Object helloAdvice() {
    // System.out.println("하하하");
    // return null; // 메서드 진입이 안됨
    // }

    @Around("hello()")
    public Object helloAdvice(ProceedingJoinPoint jp) throws Throwable { // 리플렉션을안해도 알아저 주입해줌, 꺼내쓰기만 하면됨 나중에 뭐있는지 한번
        // 확인하자
        Object[] args = jp.getArgs(); // 타입을 알수 없으니 오브젝트 배열로 받자
        System.out.println("파라메터 사이즈 : " + args.length); // v2 파라메터 사이즈 : 1 // v1파라메터 사이즈 : 0 -> 매개변수의 크기를 확인할 수 있음

        for (Object arg : args) { // object 의 크기는 아무도 알지 못해
            if (arg instanceof String) { // 다운캐스팅 가능
                String username = (String) arg;
                System.out.println(username + "님 안녕");
            }

        }
        return jp.proceed(); // 메서드로 진입. (null 인 경우 진입이 안됨)

    }
}
  • ProceedingJoinPoint jp : 스프링 AOP에서 Advice 메서드에서 사용되는 파라미터 중 하나. 
    1. @Around 어노테이션 -> 대상 메서드의 실행 전과 후에 Advice 메서드(log)가 실행.
    2. ProceedingJoinPoint를 이용하여 대상 메서드를 호출
    3. 실행 전과 후에 로그를 출력=>  Advice 메서드에서 ProceedingJoinPoint를 사용하면, 대상 객체의 메서드를 실행하면서 추가적인 로직을 수행 할수 있다.
  • arg instanceof *** : 객체의 타입을 체크하는 연산자
728x90
반응형

'JAVA Spring' 카테고리의 다른 글

[Ajax] 좋아요 만들기!  (0) 2023.06.18
[Ajax] 썸네일 수정 contentType 설정  (0) 2023.06.17
SHA-256 해시 함수 코드  (0) 2023.05.12
spring 정리  (0) 2023.05.09
JDBC를 이용한 자바 dbapp  (0) 2023.02.13