본 포스팅의 예제는 STS 또는 Eclipse를 사용하지 않고 Intellij를 통해 구현하고 있습니다.
그래서 기존의 STS(Spring Tool Studio)에서 생성된 Spring 프로젝트의 스프링 관련 설정 파일명과
프로젝트 구조가 약간 다를 수 있습니다.Intellij 스프링 mvc 프로젝트 생성 포스팅을 참고해주시면 감사하겠습니다.
Spring-MVC 기본 개념 및 테스트 예제 관련 포스팅 링크
순서 | 포스팅 제목 |
1 | Intellij에서 Spring MVC Project 생성하기 |
2 | Spring MVC - MariaDB 연결테스트 |
3 | Spring MVC - Mybatis 설정 및 테스트 |
4 | SpringMVC 구조 |
5 | SpringMVC + Mybatis |
6 | Spring MVC Controller 작성 연습 |
Spring-MVC 게시판 예제 이전 포스팅 링크
순서 | 포스팅제목 |
1 | IntelliJ를 이용한 Spring MVC Project 생성 하기 |
2 | Bootstrap AdminLTE Template 적용하기 |
3 | ExceptionResovler : 예외페이지 처리 |
1. AOP (Aspcet Orient Programming)
# AOP(Aspcet Orient Programming)란?
AOP용어 자체를 한글로 바꾸게 되면 측면 지향 프로그래밍입니다. 측면이 개발에서 의미하는 것은 비지니스 로직은 아니지만 반드시 해야 할 작업을 의미합니다. 다시 쉽게 말해서 정말 기능을 구현하는데 있어서 핵심적인 작업은 아니지만 반드시 해야 되는 공통된 작업이라고 할 수 있습니다. 이러한 것들을 횡단관심사(cross-concern)라고 합니다. 횡단관심사는 시스템의 곳곳에서 공통으로 사용되지만, 그 자체가 목적이 아니라 시스템의 완성도를 높여주는 역할을 해줍니다. 예를 들면 보안처리나 로그 기록, 트랜잭션과 같은 번거로운 작업들을 말합니다.
위 그림을 통해 설명하자면 일반적인 로직의 흐름에서는 계정, 게시판, 계좌이체를 처리할 떄마다 동일하게 권한을 체크하고 로그를 기록하고 트랜잭션을 처리해줘야하기 떄문에 동일한 코드가 반복적으로 삽입됩니다. 하지만 AOP는 이러한 횡단 관심사를 종단으로 삽입할 수 있게 합니다. 기존에는 각각의 계층에서 직접 코드로 작성하여 처리하던 것들을 공통적인 관심을 처리하는 모듈을 분리해 개발한 뒤, 필요한 시점에 자동으로 소스코드가 삽입되도록 하는 것입니다.
# AOP(Aspcet Orient Programming)와 관련된 용어
AOP의 구현은 Porxy 패턴이라는 방식을 통해 이루어집니다. 외부에서 특정한 객체를 호출하면 실제 객체(Target)를 받감싸고 있는 바깥쪽 객체(Proxy)를 통해 호출이 전달 됩니다. Proxy객체는 AOp의 기능이 적용된 상태에서 호출을 받아 사용되고 실체 객체와 동일한 타입을 자동으로 생성 할 수 있기 떄문에 외부에서는 실제 객체와 동일한 타입으로 호출 할 수 있습니다.
AOP를 이해하기 위해서는 아래의 용어의 이해가 필수적입니다.
용어 | 설명 |
Aspect | 공통 관심사에 대한 추상적인 명칭, 예를 들어 로깅이나 보안 트랜젝션 같은 기능 자체에 대한 용어 |
Advice | 실제로 기능을 구현한 객체를 뜻하는 용어 |
Join points | 공통 관심사를 적용할 수 있는 대상, Spring AOP에서는 각 객체의 메서드가 해당됩니다. |
Pointcuts | 여러 메서드 중 실제 Advice가 적용될 메서드 |
target | 대상 메서드가 가지는 객체 |
Proxy | Advice가 적용되었을 떄 만들어지는 객체 |
Introduction | target에는 없는 새로운 메서드나 인스턴스 변수를 추가하는 기능 |
Weaving | Advice나 target이 결합되어서 프록시 객체를 만드는 과정 |
좀 더 자세한 설명이 필요한 용어는 아래와 같습니다.
● Advice : 실제로 적용 시키고 싶은 코드 자체를 의미합니다. 개발자가 만드는 것은 Aspcect가 아닌 클래스를 제작하고 @Advice 어노테이션을 적용 하는 것입니다. 예를 들면 로그 출력기능, 파라미터 체크 기능 자체는 Aspect라는 용어로 부르지만 실제 구현 시에는 Adice를 제작한다고 표현 합니다.
● Target : 실제 비지니스 로직을 수행하는 객체를 의미 합니다. Aspect를 적용해야하는 대상 객체를 의미 합니다
● Join points : 작성된 Advice가 작동되는 위치를 의미합니다. 예를 들면 HomeController 의 메인페이지 접속 예외 페이지 발생 만을 골라서 Advice를 적용할 수 있는데 이 떄 HomeController의 모든 메서드는 JoinPoint가 됩니다.
● Pointcuts : 여러 Join points 중에서 Advice를 적용할 대상을 선택하는 정보를 의미합니다. 이를 통해 특정 메서드는 Advice가 적용된 형태로 동작하게 됩니다.
# Advice의 종류
Advice 종류 | annotation | 설명 |
Before Advice | @Before | joinpoint 전에 수행되는 Advice |
Affter Advice | @After | joinpoint 실행 직후에 Advice |
Around Advice | @Around | joinpoint 실행 전후로 실행되는 Advice |
After Retuning Advice | @AfterReturning | joinpoint가 성공적으로 완료되었을 경우 실행되는 Advice |
After Throwing Advice | @AfterThrowing | joinpoint의 함수가 예외를 던지면서 종료될 경우 |
2. AOP(Aspcet Orient Programming) 적용을 위한 준비
# AOP(Aspcet Orient Programming)와 관련된 라이브러리를 추가 : pom.xml
Spring-AOP 라이브러릴 추가해주세요.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${org.springframework-version}</version>
</dependency>
AOP기능을 적용하기 위해서 AspectJ 언어의 문법을 이용하기 떄문에 이와 관련된 라이브러리를 추가 해주세요.
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
# AOP 설정 : dispatcher-servlet.xml
dispatcher-servlet.xml에 아래와 같은 설정을 추가해주세요. 아래의 설정을 통해 자동으로 AspectJ라이브러리를 통해 Porxy객체를 생성하는 용도로 사용됩니다.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--AOP 설정을 통한 자동적인 Proxy 객체 생성을 위한 설정-->
<aop:aspectj-autoproxy/>
<aop:config>
</aop:config>
</beans:beans>
3. AOP 적용을 위해 사용자 어노테이션 추가하기
AOP 적용을 위해 사용자 어노테이션을 추가 해주겟습니다. src/main/java/com/spring/pratice/commons/annotation 패키지에 아래와 같이 LogException를 생성하고, 아래와 같이 코드를 작성 해주세요
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogException {
}
annotation | 설명 |
@Target(ElementType.METHOD) | annotation이 Method 에서 선언된다는 의미 |
@Retention(RetentionPolicy.RUNTIME) | annotation이 프로그램이 실행되는 동안 유지된다는 의미 |
4. 프로젝트에 AOP 적용하기
# AOP를 이용하여 로그 출력을 도와줄 LogAdivice 클래스 작성
AOP를 이용하여 로그를 출력하는 기능을 처리해 보겠습니다.
먼저 /src/main/java/기본패키지/commons/aop 패키지에 아래와 같이 LogAdvice를 생성하고 아래와 같이 코드를 작성해주세요
각 계층에서 로직이 실행될 떄 마다 클래스명 메서드명 파라미터를 출력하도록 하였습니다
@Component
@Aspect
public class LogAdvice {
/*
* private : 외부에서 로그를 가로채지 못하도록 하기 위해
* static final : 로그 내용이 변동 되지 않으므로
* 로깅툴을 사용하는 이유 : system.out.println 명령어는 IO 리소스를 많이 사용하여 시스템이 느려질 수 있다. 로그를 파일로 저장하여 분석 할 필요가 있다.
*/
private static final Logger logger = LoggerFactory.getLogger(LogAdvice.class);
@AfterThrowing(value = "@annotation(com.spring.practice.commons.annotation.LogException)", throwing = "exception")
public void exception(JoinPoint joinPoint, Exception exception) {
logger.error("error class : " + exception.getClass().getSimpleName());
logger.error("error method name : " + joinPoint.getSignature().getName());
logger.error("error cause : " + exception.getCause());
logger.error("errorMessage : " + exception.getMessage());
}
@AfterReturning(value = "@annotation(com.spring.practice.commons.annotation.LogException)", returning = "result")
public void AfterReturning(JoinPoint joinPoint, Object result) {
System.out.println("실행된 클래스 : " + joinPoint.getTarget().getClass().getSimpleName());
System.out.println("실행된 메서드 : " + joinPoint.getSignature().getName());
System.out.println("전달된 파라미터 : " + Arrays.toString(joinPoint.getArgs()));
}
위의 코드에서 주의해서 봐야할 점이나 알아두어야 할 내용은 아래와 같습니다
- @Component : 스프링의 빈으로 인식되기 위한 annotation
- @Aspect : AOP 기능을 하는 클래스에 반드시 추가 해야 할 annotation
- @AfterThrowing : 로직 실행시 예외 처리가 발생 할 시 처리 하는 annotation
- @AfterReturning : 로직 실행이 정상적으로 완료 되었을 경우 처리 하는 annotation
# 특정 로직을 실행했을 떄의 콘솔에 찍힌 로그
AOP를 적용하고 난 뒤 메인페이지에 접속했을 떄 콘솔에 출력되는 로그 내용이다.
실행된 클래스 : HomeController
실행된 메서드 : homePage
전달된 파라미터 : []
'스프링 프레임워크 > 스프링 MVC' 카테고리의 다른 글
# Spring MVC 게시판 예제 06 - 회원가입 유효성 검사 (Feat. JavaScript) (0) | 2023.02.23 |
---|---|
# Spring MVC 게시판 예제 05 - 회원가입 처리하기 (2) | 2023.02.22 |
# Spring MVC 게시판 예제 03 - ExceptionResolver : 예외페이지 처리 (0) | 2023.02.21 |
# Spring MVC 게시판 예제 02 - Boostrap Template 적용 (AdminLTE) (1) | 2023.02.20 |
# Spring MVC 게시판예제 01 - 프로젝트 생성 및 설정 (0) | 2023.02.20 |
댓글