• Home
  • About
    • Young's Github Pages photo

      一日不作一日不食

    • About
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

Java EE 정리 46

02 May 2019

Reading time ~2 minutes

Java EE 정리 46 - Spring AOP(1)


Spring AOP

  • AOP(Aspect Oriented Programming, 관점지향 프로그래밍)
  • 종단 관심사 처리
    • == 상속, 부모에서 정의된 업무를 사용하기 싫어도 자식이 사용함

01

  • 횡단 관심사 처리
    • 주기능에서 부기능을 분리할 수 있다
      • 주 업무로직에서 부가적인 기능의 코드가 분리되어 코드의 복잡도가 낮아진다
    • 상속과는 다르게 부가적인 기능이 필요한 코드에만 적용할 수 있다
    • 아래 예와 같이 지문 찍는건 수업을 듣는 것과 아무런 관련이 없는 부기능(횡단 관심사)
    • 공통 로직을 중요하게 생각하는 설계에서는 AOP를 사용하는게 좋다

02

AOP 용어

03

Advice가 동작하는 시점

04

Spring AOP 설치

  • aspectjrt.jar, aspectjweaver.jar가 필요
    • aspectjrt는 기본으로 Spring legacy에서 추가됨, weaver만 maven repository에서 다운 설치
  • pom.xml dependency 추가로 설치, WEB-INF/lib에 복붙으로 옮겨넣기
    • Maven Repository

05

<!-- pom.xml -->
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.3</version>
</dependency>
  • 설정파일에 AOP 사용 설정 추가
<aop:aspectj-autoproxy/>

06

  • Annotation 사용 설정, AOP 사용 설정
<!-- application-context.xml -->
...
      <context:annotation-config/>
      <context:component-scan base-package="kr.co.sist"/>
      <context:component-scan base-package="kr.co.sist.dao"/>
      <context:component-scan base-package="kr.co.sist.dao.*"/>
      <context:component-scan base-package="kr.co.sist.service"/>
      <context:component-scan base-package="kr.co.sist.service.*"/>
      
      <!-- AOP : 설정 후 annotation을 사용할 수 있음 -->
      <aop:aspectj-autoproxy/>
</beans>

AOP Annotation - 클래스 위에 설정

  • @Aspect
    • Advice와 Pointcut의 합
@Aspect
class Test { ... }

AOP Annotation - 메소드 위에 설정

  • method 위에 설정
  • Advice가 동작하는 target method와 시점을 정의
  • @Before
    • target method 호출 전에 Advice가 동작
@Before("execution(pointcut)")
public void someMethod() { ... }
  • @After
    • target method 호출 후 Advice가 동작
@After("execution(pointcut)")
public void someMethod() { ... }
  • @AfterReturning
    • target method 호출 후 return값이 반환된 후 Advice가 동작
@AfterReturning("execution(pointcut), return=리턴값")
public String someMethod() { ... } 
  • @AfterThrowing
    • target method에서 예외를 날린 후 Advice가 동작
@AfterThrowing("execution(pointcut)")
public String someMethod() throws SQLException { ... }
  • @Around
    • target method 전 후 Advice가 동작
@Around("execution(pointcut)")
public String someMethod() { ... }
  • target에 JoinPoint를 설정하는 표현식 Pointcut
    • 적용 대상은 method(target method)
@Before("execution(접근지정자 반환형 패키지명.클래스명.메소드명(매개변수타입))")
// 접근지정자 반환형 패키지명.클래스명 까지는 생략가능
@Before("execution(메소드명(매개변수타입))")

// ".."을 사용하면 모든 대상
// "*"을 사용할 수 있음(와일드 카드)
@Before(execution(public void kr.co.sist.controller.*Controller*.testMethod)
  • Advice 내에선 모든 객체를 받을 수 있다
    • JoinPoint, ProceedingJoinPoint 두가지 사용하여 target에서 사용되는 parameter, return 값을 받을 수 있다
  • DI와 AOP를 사용한 예제

07

public class ItemDomain {
      
  private String itemNo, item;
  // getter, setter 생성
...
public interface ItemDAO {
      
  public ItemDomain selectItem(String name) throws NumberFormatException;
}
@Component
public class ItemDAOImpl implements ItemDAO {
  @Override
  public ItemDomain selectItem(String name) throws NumberFormatException {
    return new ItemDomain("IT_T01", name+"의 자신감있는 태도,  해박한 전문지식, 포장기술");
  }
}
public interface ItemService {
      
  public ItemDomain searchItem(String name);
}
@Component
public class ItemServiceImpl implements ItemService {
  @Autowired
  private ItemDAO i_dao;
  
  @Override
  public ItemDomain searchItem(String name) {
    
    ItemDomain id = i_dao.selectItem(name);
    System.out.println(id.getItemNo()+" / "+id.getItem());
    
    return id;
  }
}
public class AopRun {
  
  public void execute() {
    ApplicationContext ac =
        new  ClassPathXmlApplicationContext("kr/co/sist/run/application-context.xml");
    
    ItemService is = ac.getBean(ItemService.class);
    ItemDomain id = is.searchItem("김희철");
  }
  
  public static void main(String[] args) {
    AopRun ar = new AopRun();
    ar.execute();
  }
}

08

  • 이제 AOP를 적용시켜보자
    • target method 호출 전에 실행되는 advice
    • target method는 String을 매개변수로 갖는 searchItem이란 이름의 method
@Aspect
@Component
public class ItemAop {
      
      @Before("execution(* searchItem(String))")
      public void before() {
            System.out.println("before advice");
      }
}

09

  • target method 호출 후 실행되는 advice
@Aspect
@Component
public class ItemAop {
      
      @After("execution(* searchItem(String))")
      public void after() {
            System.out.println("after advice");
      }
}

10



Java EESpring