📒 Spring 숙련
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
애너테이션이 붙어있는 메서드에만 작업이 추가된 것을 볼 수 있다.