HelloZ

(4) 스프링_Aop에 대해 알아보자 본문

웹 공부/- Spring Framework

(4) 스프링_Aop에 대해 알아보자

헬로z 2019. 8. 13. 11:05

지난 시간에 Mybatis를 설정하여 적용하고 User 정보를 삽입하는 부분까지 프로젝트를 진행하였다. 

이번에는 Aop에 대해서 알아보도록 하자.


AOP란? 

- 부가기능에 해당하는 기능의 모듈화 작업은 기존의 객체지향 설계 패러다임과 구분되는 새로운 특성이 있다고 판단

 

Aspect

- 객체 지향 기술에서 부가기능 모듈을 부르는 이름

- 애스펙트 자체로는 애플리케이션의 핵심기능을 담고 있지는 않지만 요소요소마다 공통 관심사항이 될 수 있음

- 즉, 애플리케이션을 구성하는 한 가지 측면

 

Aspect의 분리

- 왼쪽

  • 부가기능이 핵심기능의 모듈에 침투해 들어가면서 설계와 코드가 지저 분해짐

  • 부가기능 코드가 여기저기 메소드에 마구 흩어져서 나타나고 코드는 중복됨

 

  • 코드 사이에 침투한 부가기능을 독립적인 모듈인 애스팩트로 구분

  • 각각 성격이 다른 부가기능은 다른 면에 존재하여 독립적으로 그 코드를 살펴볼 수 있음

Aspect Oriented Programming

- 관점지향 프로그래밍

- 애플리케이션의 핵심적인 기능에서 부가적인 기능을 분리하여 애스펙트라는 모듈로 구분하여 설계하고 개발하는 방법

- AOP는 OOP를 돕는 보조적인 기술이지 OOP를 대체하는 기술은 아님

- 애플리케이션을 다양한 측면에서 독립적으로 모델링하고, 설계하고, 개발할 수 있도록 함

 

AOP 용어

타겟(Target)
  • 부가기능을 부여할 대상 (ex: 클래스)
어드바이스(Advice)
  • 타켓에게 제공할 부가기능을 담은 모듈
  • 객체로 정의하기도 하지만 메소드 레벨에서 정의하기도 함
조인 포인트 (Join Point)
  • 어드바이스가 적용될 수 있는 위치
  • 스프링 프록시 AOP에서 조인 포인트는 메소드의 실행 단계임
포인트컷 (Pointcut)
  • 어드바이스를 적용할 조인 포인트를 선별하는 작업 또는 그 기능을 정의한 모듈
  • 스프링의 포인트컷은 특정 타입 객체의 특정 메소드를 선정하는 기능

AOP에 대한 설명은 여기까지 하며, 이제 이전 프로젝트에 AOP기능을 구현해보도록 한다.

앞서 만들었던 회원가입 기능(단순 DB 삽입)을 서비스(AOP 타겟) 로 구현하며 위 서비스의 특정 함수를 실행할 때 실행 전 후로 부가기능(간단 한 문구 출력) 삽입을 하도록 하겠다.

 

pom.xml에 다음과 같이 추가

<!-- Spring AOP + AspectJ -->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-aop</artifactId>
	<version>4.2.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjrt</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjweaver</artifactId>
	<version>1.8.6</version>
</dependency>

project.one.service 패키지 생성

-> UserService.java 파일 생성 후 다음 코드 작성

package project.one.service;

import project.one.domain.User;
import project.one.repository.UserMapper;
import org.springframework.stereotype.Service;
import javax.inject.Inject;
import java.util.Date;

@Service
public class UserService { //타겟
	@Inject
	private UserMapper userMapper;
	public Boolean signup(User user) {
		if(user.getEmail() == null || user.getPassword() == null)
	return false;
    
	userMapper.insert(user);
	System.out.println(“User created: " + new Date());
	return true;
	}
}

스프링 설정 파일 (Service.xml)에 다음 코드 추가

<aop:aspectj-autoproxy />
<bean id="userServiceAspect" class="project.one.aop.AopTester" />

usercontroller에서 signup을 다음과 같이 수정

@Transactional
@RequestMapping(value="/signup", method= RequestMethod.POST)
@ResponseBody
public String signup(@ModelAttribute User user) {
	userService.signup(user);
	return "success";
}


@AfterReturning

Pointcut에 지정한 함수가 실행 완료 후 결과값을 활용

@AfterReturning(pointcut = "execution(* project.one.service.UserService.signup(..))", returning= "result")
public void afterReturningMethod(JoinPoint joinPoint, Object result) {
	System.out.println("After Returning " + joinPoint.getSignature().getName() + ": " + new Date() + ", Value = " + result);
}

@Around

- @Before와 @After를 통합하여 실행 가능

@Around("execution(* project.one.service.UserService.signup(..))")
public void aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
	System.out.println("@Around is running!");
	System.out.println("Before " + joinPoint.getSignature().getName());
	joinPoint.proceed();
	System.out.println("After " + joinPoint.getSignature().getName());
}

참고 : 포인트 컷 표현식

- 표현식과 선정 결과

AspectJ 포인트컷 표현식의 메소드 선정 결과

 

AspectJ 포인트컷 표현식의 메소드 선정 결과

Comments