관점 지향 프로그래밍
- 관심사의 분리
- 핵심로직은 하니지만 코드에 전반적으로 반복적으로 사용하며, 필요한 로직들
- 횡단 관심사(cross-concerns)
- Aspect : 추상 명사로 횡단 관심사를 의미한다.
- 로깅, 보안, 트랜잭션 등
- Advice : 비즈니스 로직을 수행하기 전후에 할 것을 타겟한테 추가적으로 지정해 주는 역할.
- Target : 비즈니스 로직을 가지고 있는 객체(일하는 사람). 순수한 비즈니스 로직을 의미하고, 어떠한 관심사들과도 관계를 맺지 않는다. 순수한 core이다.
- Proxy : 대리자 형태이다. 조인트포인트가 메소드다.
- JoinPoint : Target 객체가 가진 메서드.
- Pointcut : Target에는 여러 메서드가 존재하기 때문에 어떤 메서드에 관심사를 결합할 것인지를 결정해야 하는데, 이 결정을 'Pointcut'이라 한다.
특정한 비즈니스 객체의 메소드가 실행전후의 코드 : Before, After Advice
Around Advice : 실행과 예외 발생에 관여하는 규모가 제일 큰 Advice이다.
Advice를 어떤 JoinPoint에 결합할 것인지를 결정한다. AOP에서 Target은 결과적으로 Pointcut에 의해서 자신에게는 없는 기능들을 가지게된다. Pointcut은 다양한 형태로 선언해서 사용할 수 있는데 주로 사용되는 설정은 다음과 같다.
execution이 기본적으로 많이 쓰인다.
/
<filter>
추가<%@ page session="false" language="java"
contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
pom.xml 버전수정(java ver, junit, log4j,servlet-api,plugin)(메이븐 업데이트를 해야 자바버전이 바뀜)
<org.aspectj-version>1.6.10</org.aspectj-version>
의 버전을 1.6.10 → 1.9.0 변경
<org.slf4j-version>1.6.6</org.slf4j-version>
의 버전을 1.6.6 → 1.7.25 변경
변경된 버전이 다음 dependency에 적용된다.
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<dependency>
추가server를 clean 할 때 context가 recovery되니까 다시 /
로 수정
weaver추가
오류가 나는것은 이전에 있는 버전을 물고 있어서 그렇다. (이전에 디플로이 된 내용을 물고있어서 그렇다)
환경설정이 모두 끝났으면 clean후 서버 재시작
return Integer.parseInt(str1) + Integer.parseInt(str2);
잘못괸 문자열 즉 숫자가 아닌 문자열이 들어와서 넘버포맷 익셉션이 발생할수있다.
doAdd : 비즈니스 로직을 가지고 있는 핵심 객체
@Aspect 가 붙은 클래스는 Advice를 구현하는 역할
@Component : bean으로 등록해서 쓰겠다
@Before advice는 안쪽에 인자를 지정해야되는데 이 인자에는 포인트컷이 들어간다.
접근제한자가 없이 다 받아 들이겠다.
메서드의 인자인데 알아서 매핑해서 채우라는뜻이다.
root context 네임스페이스 context 선택하고 다음과 같이 작성한다.
context:component-scan : 스프링에서 인식해서 씀
aop:aspectj추가
package com.zerock.service;
import static org.junit.Assert.fail;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import lombok.Setter;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
public class SampleServiceTests {
@Setter(onMethod_=@Autowired)
private SampleService service;
@Test
public void test() {
fail("Not yet implemented");
}
}
ReplyController에서
문자열을 2개이상 표현할때 중괄호로 묶어서 배열로 쓴다는것
@ContextConfiguration({"file:src/main/webapp/WEB-INF/spring/root-context.xml"})
여기서 {}로 감싸져 있는것을 볼수있다.
여기서 예외 발생해서 받는건 스프링 시스템엣 ㅓ처리
파라미터를 가지고 한번 해보져 전에( 다시 듣기)
기존코드를 수정하지않고 파라미터가 뭔지 체크할수있다.
파라미터의 값이 잘못되어서 예외가 발생하는 경우가 있다. AOP의 @AfterThrowing 어노테이션은 지정된 대상이 예외를 발생한 후에 동작하면서 문제를 찾을 수 있도록 도와준다.
@AfterThrowing(pointcut = "execution(* com.zerock.service.SampleService*.*(..))", throwing="ex")
public void logException(Exception ex) {
log.info("오류 처리 Advice");
log.info("Exception : " + ex);
}
public Object logTime(ProceedingJoinPoint pjp) {
log.info("Around 이전 실행 코드");
long start = System.currentTimeMillis();
Object result = null;
try {
pjp.proceed();
} catch (Throwable ex) {
ex.printStackTrace();
}
long end = System.currentTimeMillis();
log.info("Around 이후 실행 코드");
log.info("수행 시간 : " + (end - start));
return result;
}
위의 로직은 매우 많이 쓰인다. 비즈니스 로직이 실제로 실행하는데 걸리는 시간을 밀리세컨드 단위로 측정할 수 있다.