AOP

cy8erpsycho·2023년 9월 7일
0

스프링

목록 보기
25/29
post-thumbnail

AOP

관점 지향 프로그래밍

  • 관심사의 분리
    • 핵심로직은 하니지만 코드에 전반적으로 반복적으로 사용하며, 필요한 로직들
    • 횡단 관심사(cross-concerns)



AOP 용어들

  • Aspect : 추상 명사로 횡단 관심사를 의미한다.
    • 로깅, 보안, 트랜잭션 등
  • Advice : 비즈니스 로직을 수행하기 전후에 할 것을 타겟한테 추가적으로 지정해 주는 역할.
  • Target : 비즈니스 로직을 가지고 있는 객체(일하는 사람). 순수한 비즈니스 로직을 의미하고, 어떠한 관심사들과도 관계를 맺지 않는다. 순수한 core이다.
  • Proxy : 대리자 형태이다. 조인트포인트가 메소드다.
  • JoinPoint : Target 객체가 가진 메서드.
  • Pointcut : Target에는 여러 메서드가 존재하기 때문에 어떤 메서드에 관심사를 결합할 것인지를 결정해야 하는데, 이 결정을 'Pointcut'이라 한다.

Advice

특정한 비즈니스 객체의 메소드가 실행전후의 코드 : Before, After Advice
Around Advice : 실행과 예외 발생에 관여하는 규모가 제일 큰 Advice이다.

Pointcut

Advice를 어떤 JoinPoint에 결합할 것인지를 결정한다. AOP에서 Target은 결과적으로 Pointcut에 의해서 자신에게는 없는 기능들을 가지게된다. Pointcut은 다양한 형태로 선언해서 사용할 수 있는데 주로 사용되는 설정은 다음과 같다.

execution이 기본적으로 많이 쓰인다.



AOP 실습

  • 루트 컨텍스트 /
  • web.xml 한글인코딩 <filter> 추가
  • home.jsp 필터적용 확인
<%@ page session="false" language="java" 
contentType="text/html; charset=UTF-8" 
	pageEncoding="UTF-8"%>
  • pom.xml 버전수정(java ver, junit, log4j,servlet-api,plugin)(메이븐 업데이트를 해야 자바버전이 바뀜)

    • AOP 버전 수정

<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>	

  • pom.xml <dependency> 추가
    spring-test
    spring-jdbc
    mybatis
    mybatis-spring
    HikariCP
    log4jdbc-log4j2-jdbc4
    ojdbc8
    lombok
    jackson-databind
    jackson-dataformat-xml
    gson

server를 clean 할 때 context가 recovery되니까 다시 /로 수정

  • root-context, servlet-context 변경

weaver추가

오류가 나는것은 이전에 있는 버전을 물고 있어서 그렇다. (이전에 디플로이 된 내용을 물고있어서 그렇다)

환경설정이 모두 끝났으면 clean후 서버 재시작

✍SampleService 인터페이스 작성

✍SampleServiceImpl 작성

return Integer.parseInt(str1) + Integer.parseInt(str2);
잘못괸 문자열 즉 숫자가 아닌 문자열이 들어와서 넘버포맷 익셉션이 발생할수있다.

doAdd : 비즈니스 로직을 가지고 있는 핵심 객체

✍LogAdvice 작성

@Aspect 가 붙은 클래스는 Advice를 구현하는 역할
@Component : bean으로 등록해서 쓰겠다

@Before advice는 안쪽에 인자를 지정해야되는데 이 인자에는 포인트컷이 들어간다.

접근제한자가 없이 다 받아 들이겠다.

메서드의 인자인데 알아서 매핑해서 채우라는뜻이다.



AOP 설정

root context 네임스페이스 context 선택하고 다음과 같이 작성한다.
context:component-scan : 스프링에서 인식해서 씀

aop:aspectj추가



AOP 테스트

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"}) 여기서 {}로 감싸져 있는것을 볼수있다.

여기서 예외 발생해서 받는건 스프링 시스템엣 ㅓ처리

파라미터를 가지고 한번 해보져 전에( 다시 듣기)


args를 이용한 파라미터 추적

기존코드를 수정하지않고 파라미터가 뭔지 체크할수있다.


@AfterThrowing

파라미터의 값이 잘못되어서 예외가 발생하는 경우가 있다. AOP의 @AfterThrowing 어노테이션은 지정된 대상이 예외를 발생한 후에 동작하면서 문제를 찾을 수 있도록 도와준다.

	@AfterThrowing(pointcut = "execution(* com.zerock.service.SampleService*.*(..))", throwing="ex")
	public void logException(Exception ex) {
		log.info("오류 처리 Advice");
		log.info("Exception : " + ex);
	}


@Around와 ProceedingJoinPoint

	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;
	}

위의 로직은 매우 많이 쓰인다. 비즈니스 로직이 실제로 실행하는데 걸리는 시간을 밀리세컨드 단위로 측정할 수 있다.

0개의 댓글