230623_ AOP원리

hoy_·2023년 6월 23일
0

Today, I Learned

목록 보기
25/36

1. 오늘의 일정

  1. 📒 Spring 숙련




2. 배운 내용

  1. AOP (Aspect Oriented Programming)
  • 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 공통된 로직이나 기능을 하나의 단위로 묶어 모듈화 하는 것.

class AopMain

public class AopMain {
    public static void main(String[] args) throws Exception {
        Class myClass = Class.forName("com.fastcampus.ch3.aop.MyClass");
        Object o = myClass.newInstance();

        MyAdvice myAdvice = new MyAdvice();

        for (Method m : myClass.getDeclaredMethods()) {
            myAdvice.invoke(m, o, null);
        }
    }
}

class MyAdvice

class MyAdvice {
    void invoke(Method m, Object obj, Object... args) throws Exception {
        System.out.println("[before]"); // 공통으로 들어갈 코드
        m.invoke(obj, args);
        System.out.println("[after]"); // 공통으로 들어갈 코드
    }
}

class MyClass

class MyClass {
    void aaa() {
        System.out.println("aaa() is calssed.");
    }

    void aaa2() {
        System.out.println("aaa2() is calssed.");
    }

    void bbb() {
        System.out.println("bbb() is calssed.");
    }
}

실행창

호출할 메서드와 전/후 공통 작업을 각각 지정해주지 않아도 모든 메서드에 코드가 추가되어 출력된다. 이처럼 흩어진 관심사를 모듈화하고 핵심적인 비즈니스 로직에서 분리하여 재사용하겠다는 것이 AOP의 취지다.

만약 특정 메서드에만 작업을 추가하고 싶다면 어떻게 해야할까?

Pattern과 Matcher를 사용하여 특정 문자로 시작하거나 특정 애너테이션이 붙어있는 등, 조건을 주어 일치하는 메서드에만 코드를 추가하도록 만들 수 있다.

class AopMain

public class AopMain {
    public static void main(String[] args) throws Exception {
        Class myClass = Class.forName("com.fastcampus.ch3.aop.MyClass");
        Object o = myClass.newInstance();

        MyAdvice myAdvice = new MyAdvice();

        for (Method m : myClass.getDeclaredMethods()) {
            myAdvice.invoke(m, o, null);
        }
    }
}

class MyAdvice

class MyAdvice {
    Pattern p = Pattern.compile("a.*"); // a로 시작하는 문자열

    boolean matches(Method m) { // 지정된 메서드가 패턴에 일치하는지
        Matcher matcher = p.matcher(m.getName());
        return matcher.matches();
    }

    void invoke(Method m, Object obj, Object... args) throws Exception {
        if (m.getAnnotation(Transactional.class) != null)
            System.out.println("[before]"); // 공통으로 들어갈 코드
        m.invoke(obj, args); // aaa(), aaa2(), bbb() 호출

        if (m.getAnnotation(Transactional.class) != null)
            System.out.println("[after]"); // 공통으로 들어갈 코드
    }
}
class MyClass {
    @Transactional
    void aaa() {
        System.out.println("aaa() is calssed.");
    }

    void aaa2() {
        System.out.println("aaa2() is calssed.");
    }

    void bbb() {
        System.out.println("bbb() is calssed.");
    }
}

실행창

a로 시작하고 @Transactional 애너테이션이 붙어있는 메서드에만 작업이 추가된 것을 볼 수 있다.



profile
배우는 사람

0개의 댓글