본문 바로가기

Archived(Programming)/Spring #2(기초)

PointCut 표현식과 Advisor 구현

# PountCut 표현식 문법

  • AspectJ 포인트컷 표현식은 포인트컷 지시자를 이용하여 작성함
  • 대표적으로 execution() 지시자를 사용해 표현

execution 지시자 문법구조

 

PointCut 표현식 예시

ex) execution(* hello(..))

hello라는 이름을 가진 메소드를 선정(..은 파라미터는 모든 종류를 허용)

 

ex) execution(* hello())

hello 메서드 중 파라미터가 없는 것만 허용

 

ex) execution( * myspring.user.service.UserServiceImpl.*(..))

myspring.user.service.UserServiceImpl 클래스를 직접 지정하여 해당 클래스의 모든 메서드 지정

 

ex) execution( * myspring.user.service.*.*(..))

myspring.user.service 패키지의 모든 클래스에 적용(서브패키지의 클래스는 미포함)

 

ex) execution(* myspring.user.service..*.*(..))

myspring.user.service 패키지와 서브패키지의 모든 클래스를 포함

 

ex) execution(* *..Target.*(..))

Target이라는 이름의 모든 클래스에 적용(다른 패키지에 같은 이름의 클래스가 있어도 적용이 된다는 점 유의)

 

# Spring AOP 구현 방식

1) XML 기반의 POJO 클래스 이용한 AOP 구현

  • 부가기능을 제공하는 Advice 클래스 작성
  • XML 설정 파일에 <aop:config>를 이용해서 Aspect를 설정(어드바이스와 포인트 컷을 설정)

2) @Aspect 어노테이션을 이용한 AOP 구현

  • @Aspect 어노테이션을 이용해서 부가기능을 제공하는 Aspect 클래스를 작성
  • Aspect 클래스는 어드바이스를 구현하는 메서드와 포인트컷을 포함
  • XML 설정 파일에 <aop:aspectj-autoproxy />를 설정

# @Aspect 어노테이션

  • Aspect 클래스를 선언할 때 사용
  • AspectJ 5버전에 새로 추가됨
  • XML 설정파일에 어드바이스와 포인트컷을 설정하는 것이 아니라 클래스 내부에 정의 가능
  • <aop:aspectj-autoproxy /> 태그를 설정파일에 추가시 어노테이션이 적용된 Bean을 Aspect로 사용 가능

# Advice 종류와 정의를 위한 어노테이션

Advice 종류
Advice를 정의하는 어노테이션
Advice를 정의하는 어노테이션

# JoinPoint 인터페이스

  • AOP가 적용되는 지점
  • 모든 어드바이스는 org.aspectj.lang.JoinPoint 타입의 파라미터를 어드바이스 메서드에 첫 번째 매개변수로 선언 가능
  • Around 어드바이스는 JoinPoint의 하위 클래스인 ProceedingJoinPoint 타입의 파라미터를 필수적으로 선언해야 함

주요메서드

# 실습 - 메소드 수행시간 확인 Aspect 생성

- MeasuringAspect 생성

- @Around 디바이스 활용

package kr.co.acomp.hello.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class MeasuringAspect {
	
	@Around("execution(* kr.co.acomp.hello.service.*Service.*(..))")
	public Object measuringMethodObject(
			ProceedingJoinPoint joinPoint) throws Throwable{
		
		long start = System.currentTimeMillis();
		
		// Proceed 실제 타겟 메서드 실행
		try {
			return joinPoint.proceed();
		} finally {
			long result = System.currentTimeMillis() - start;
			String targetMethodName = joinPoint.getSignature().getName(); // 메소드 이름 확인
			System.out.println(targetMethodName + "running time is " + result); // log
		}
	}
}

서비스 수정

package kr.co.acomp.hello.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import kr.co.acomp.hello.dao.ArticleDAO;
import kr.co.acomp.hello.vo.Article;

@Service 
public class BbsService {
	...
	
	public void testService() {
		System.out.println("target invoked..");
	}
}

컨트롤러 수정

package kr.co.acomp.hello.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import kr.co.acomp.hello.service.BbsService;
import kr.co.acomp.hello.vo.Article;

@Controller
@RequestMapping("/bbs") 
public class BbsController {

	@Autowired 
	private BbsService bbsService;
	
	@RequestMapping("")
	public String index() {
		bbsService.testService();
		return "home";
	}
	
	...
}

'Archived(Programming) > Spring #2(기초)' 카테고리의 다른 글

예외처리  (0) 2020.03.18
트랜잭션과 로깅  (0) 2020.03.18
AOP(Aspect Oriented Programming)  (0) 2020.03.17
Dynamic SQL  (0) 2020.03.17
Mapper XML 파일  (1) 2020.03.16