Spring(AOP)_01

2025. 2. 6. 18:31·Spring, Boot/기초 내용 정리

2025-02-05

 

 

 

 

 

 

 

 

 

 

===[Before Logic]===
[사전 처리] 비지니스 로직 수행 전 동작
==> JDBC 기반으로 insert() 메서드 기능 처리 완료
insertBoard() 메서드에서 소요된 시간 >>> 254(ms)초
===[Before Logic]===
[사전 처리] 비지니스 로직 수행 전 동작
==> JDBC 기반으로 getBoardList() 메서드 기능 처리 완료
getBoardList() 메서드에서 소요된 시간 >>> 17(ms)초
[사후 처리] 비지니스 로직 수행 후 리턴 값 >>> [BoardDTO(seq=22, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-06 18:27:16, cnt=0), BoardDTO(seq=21, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-06 18:24:58, cnt=0), BoardDTO(seq=20, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-06 18:18:20, cnt=0), BoardDTO(seq=19, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-06 18:09:57, cnt=0), BoardDTO(seq=18, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-06 18:07:05, cnt=0), BoardDTO(seq=17, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-06 18:06:54, cnt=0), BoardDTO(seq=16, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-06 09:33:18, cnt=0), BoardDTO(seq=15, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-06 09:26:46, cnt=0), BoardDTO(seq=14, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 16:47:23, cnt=0), BoardDTO(seq=13, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 16:43:23, cnt=0), BoardDTO(seq=12, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 16:38:25, cnt=0), BoardDTO(seq=11, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 15:45:06, cnt=0), BoardDTO(seq=10, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 15:39:29, cnt=0), BoardDTO(seq=9, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 15:35:28, cnt=0), BoardDTO(seq=8, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 15:32:13, cnt=0), BoardDTO(seq=7, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 15:14:52, cnt=0), BoardDTO(seq=6, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 15:13:46, cnt=0), BoardDTO(seq=5, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 15:08:09, cnt=0), BoardDTO(seq=4, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 14:43:39, cnt=0), BoardDTO(seq=3, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 14:43:37, cnt=0), BoardDTO(seq=2, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 14:41:50, cnt=0), BoardDTO(seq=1, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 14:26:03, cnt=0)]
board >>> BoardDTO(seq=22, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-06 18:27:16, cnt=0)
board >>> BoardDTO(seq=21, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-06 18:24:58, cnt=0)
board >>> BoardDTO(seq=20, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-06 18:18:20, cnt=0)
board >>> BoardDTO(seq=19, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-06 18:09:57, cnt=0)
board >>> BoardDTO(seq=18, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-06 18:07:05, cnt=0)
board >>> BoardDTO(seq=17, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-06 18:06:54, cnt=0)
board >>> BoardDTO(seq=16, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-06 09:33:18, cnt=0)
board >>> BoardDTO(seq=15, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-06 09:26:46, cnt=0)
board >>> BoardDTO(seq=14, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 16:47:23, cnt=0)
board >>> BoardDTO(seq=13, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 16:43:23, cnt=0)
board >>> BoardDTO(seq=12, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 16:38:25, cnt=0)
board >>> BoardDTO(seq=11, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 15:45:06, cnt=0)
board >>> BoardDTO(seq=10, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 15:39:29, cnt=0)
board >>> BoardDTO(seq=9, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 15:35:28, cnt=0)
board >>> BoardDTO(seq=8, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 15:32:13, cnt=0)
board >>> BoardDTO(seq=7, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 15:14:52, cnt=0)
board >>> BoardDTO(seq=6, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 15:13:46, cnt=0)
board >>> BoardDTO(seq=5, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 15:08:09, cnt=0)
board >>> BoardDTO(seq=4, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 14:43:39, cnt=0)
board >>> BoardDTO(seq=3, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 14:43:37, cnt=0)
board >>> BoardDTO(seq=2, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 14:41:50, cnt=0)
board >>> BoardDTO(seq=1, title=스프링 AOP 테스트, writer=관리자, content=스프링 AOP 테스트 중입니다..., regdate=2025-02-05 14:26:03, cnt=0)

 

		<!-- 스프링 AOP aspectjweaver 라이브러리 -->
		<dependency>
		    <groupId>org.aspectj</groupId>
		    <artifactId>aspectjweaver</artifactId>
		    <version>1.9.7</version>
		    <scope>runtime</scope>
		</dependency>
		    
		<!-- lombok 라이브러리 -->
		<dependency>
		    <groupId>org.projectlombok</groupId>
		    <artifactId>lombok</artifactId>
		    <version>1.18.36</version>
		    <scope>provided</scope>
		</dependency>

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">

	<context:component-scan base-package="com.spring" />
	
	<!-- 횡단 관심에 해당하는 Advice 클래스를 Bean으로 등록을 하자 -->
	<!-- 
		 <bean id="log" class="com.spring.model.LogAdvice" />
		 <bean id="afterReturning" class="com.spring.model.AfterReturningAdvice" />
		 <bean id="afterThrowing" class="com.spring.model.AfterThrowingAdvice" />
		 <bean id="around" class="com.spring.model.AroundAdvice" />
	-->
	<!-- @Service 애노테이션으로 Bean 등록 가능 -->
	
	
	<!-- AOP 설정 -->
	<aop:aspectj-autoproxy />
	<!-- 여기서 부터 AOP를 설정하겠다는 의미 -->
	<!-- <aop:config>								*Impl.*(..) => 클래스 이름, 모든 메서드, 인자 0개 이상
												* com.spring... => 모든 반환타입 참조
			<aop:pointcut id="allPointCut" expression="execution(* com.spring..*Impl.*(..))"/>pointcut : 핵심 로직 필터링
			<aop:pointcut id="getPointCut" expression="execution(* com.spring..*Impl.get*(..))"/>
			
			<aop:aspect ref="log">		aspect : 공통기능을 의미method="printLog" => 공통 로직 메서드
				<aop:before method="printLog" pointcut-ref="allPointCut"/>
			</aop:aspect>
			
			<aop:aspect ref="afterReturning">
				<aop:after-returning method="afterLog" pointcut-ref="getPointCut" returning="returnObj"/>
			</aop:aspect>
			
			<aop:aspect ref="afterThrowing">
				<aop:after-throwing method="exceptionLog" pointcut-ref="allPointCut" throwing="exceptionObj"/>
			</aop:aspect>
			
			<aop:aspect ref="around">
				<aop:around method="aroundLog" pointcut-ref="allPointCut"/>
			</aop:aspect>
		</aop:config> 
	-->
	<!-- 여기서 부터 AOP를 종료하겠다는 의미 -->
	
</beans>

 

package com.spring.model;

import java.util.List;

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

@Service("boardService")
public class BoardServiceImpl implements BoardService {

	@Autowired
	private BoardDAO dao;
	
	
	@Override
	public void insertBoard(BoardDTO dto) {
		// 사전 처리 작업이 로그 출력 또는 입력 값에 대한 학인 작업
		// 보안과 관련된 작업 코드 등이 해당이 될 수 있음
		//System.out.println("[사전 처리] 비지니스 로직 수행 전 동작");
		
		//LogAdvice log = new LogAdvice();
		//log.printLog();
		/*
		 * if (dto.getSeq() == 0) { throw new IllegalArgumentException(); }
		 */
		
		this.dao.inserBoard(dto);    // 비지니스 로직
	}

	@Override
	public List<BoardDTO> getBoardList() {
		//System.out.println("[사전 처리] 비지니스 로직 수행 전 동작");
		
		//LogAdvice log = new LogAdvice();
		//log.printLog();
		
		return this.dao.getBoardList();    // 비지니스 로직
	}

}

 

package com.spring.model;

import java.util.List;

import org.springframework.context.support.GenericXmlApplicationContext;

public class BoardServiceClient {

	public static void main(String[] args) {
		
		GenericXmlApplicationContext container = new GenericXmlApplicationContext("business.xml");
		
		BoardService boards = (BoardService)container.getBean("boardService");
		
		BoardDTO dto = new BoardDTO();
		
		//dto.setSeq(0);
		dto.setTitle("스프링 AOP 테스트");
		dto.setWriter("관리자");
		dto.setContent("스프링 AOP 테스트 중입니다...");

		boards.insertBoard(dto);    // 비지니스 로직
		List<BoardDTO> list = boards.getBoardList();	// 비지니스 로직
		
		for (BoardDTO board : list) {
			System.out.println("board >>> " + board.toString());
		}
		
		container.close();
	}

}

 

package com.spring.model;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Service;

@Service
@Aspect		// Aspect = Pointcut(핵심 로직) + Advice(공통 관심사항)
public class LogAdvice {

	// Pointcut을 만들어 주자
	@Pointcut("execution(* com.spring..*Impl.*(..))")
	public void allPointcut() { }	// body에 내용이 없는 메서드를 선언
	
	// printLog() 메서드가 Advice(공통 관심사항)
	@Before("allPointcut()")
	public void printLog() {
		System.out.println("[사전 처리] 비지니스 로직 수행 전 동작");
	}
}

 

package com.spring.model;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Service;

@Service
@Aspect
public class AfterReturningAdvice {

	// Pointcut을 만들어 주자
	@Pointcut("execution(* com.spring..*Impl.get*(..))")
	public void allPointcut() { }	// body에 내용이 없는 메서드를 선언
	
	@AfterReturning(pointcut = "allPointcut()", returning="returnObj")	
	public void afterLog(Object returnObj) {
		System.out.println("[사후 처리] 비지니스 로직 수행 후 리턴 값 >>> " + returnObj.toString());
	}
}

 

package com.spring.model;

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

@Service
@Aspect
public class AroundAdvice {

	// Pointcut을 만들어 주자
	@Pointcut("execution(* com.spring..*Impl.*(..))")
	public void allPointcut() { }	// body에 내용이 없는 메서드를 선언
	
	
	// around로 등록되는 Advice는 리턴타입과 매개변수가 고정이 되어야 함.
	// 반환타입은 Object 타입, 매개변수는 ProceedingJoinPoint 타입이어야 함.
	@Around("allPointcut()")
	public Object aroundLog(ProceedingJoinPoint jp) throws Throwable {
		Object obj = null;
		
		long startTime = System.currentTimeMillis();
		System.out.println("===[Before Logic]===");
		
		// 이 시점에 클라이언트가 호출한 비지니스 메서드가 실행이 됨
		obj = jp.proceed();
		
		long endTime = System.currentTimeMillis();
		
		// getSignature() : 호출되는 메서드에 대한 정보를 구해주는 메서드
		String method = jp.getSignature().getName();
		System.out.println(method + "() 메서드에서 소요된 시간 >>> " + (endTime - startTime) + "(ms)초");
		
		return obj;
	}
}

 

package com.spring.model;

import java.sql.SQLException;

import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Service;

@Service
@Aspect
public class AfterThrowingAdvice {

	// Pointcut을 만들어 주자
	@Pointcut("execution(* com.spring..*Impl.*(..))")
	public void allPointcut() { }	// body에 내용이 없는 메서드를 선언
	
	@AfterThrowing(pointcut = "allPointcut()", throwing="exceptionObj")
	public void exceptionLog(Object exceptionObj) {
		System.out.println("[예외 처리] 비지니스 로직 수행 중 예외 발생");
		
		// 발생된 예외의 타입에 따라 예외 처리 로직을 분기시켜 주면 됨
		if (exceptionObj instanceof IllegalArgumentException) {
			System.out.println("0번 글을 등록할 수 없습니다.");
		} else if (exceptionObj instanceof ArithmeticException) {
			System.out.println("0으로 숫자를 나눌 수 없습니다.");
		} else if (exceptionObj instanceof SQLException) {
			System.out.println("DB연동 과정에 문제가 있습니다.");
		} else {
			System.out.println("문제발생");
		}
	}
}

'Spring, Boot > 기초 내용 정리' 카테고리의 다른 글

Spring Boot_01  (0) 2025.02.06
Spring Boot_00  (1) 2025.02.06
Spring(AOP)_00  (0) 2025.02.06
Spring(FileUpload)_01  (0) 2025.02.06
Spring(MyBatis)_04  (0) 2025.02.05
'Spring, Boot/기초 내용 정리' 카테고리의 다른 글
  • Spring Boot_01
  • Spring Boot_00
  • Spring(AOP)_00
  • Spring(FileUpload)_01
mw41817
mw41817
일생의 개발 기록 저장소
  • mw41817
    IT 개발 일지
    mw41817
    • Index (487)
      • HTML (36)
        • 기초 내용 정리 (36)
      • CSS (29)
        • 기초 내용 정리 (29)
      • JavaScript (60)
        • 기초 내용 정리 (60)
      • JQuery (38)
        • 기초 내용 정리 (38)
      • Java (232)
        • 기초 내용 정리 (232)
      • JSP (46)
        • 기초 내용 정리 (46)
      • Spring, Boot (31)
        • 기초 내용 정리 (31)
      • DB (5)
        • Oracle SQL (5)
      • Code WorkBook (6)
        • programmers (6)
        • Baekjoon (0)
      • 기타 (1)
        • 유용한 사이트 (3)
  • 전체
    오늘
    어제
  • 글쓰기 관리
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 카테고리
    • 주인장 GitHub
  • 공지사항

  • 인기 글

  • 태그

    html #코딩 #프로그래밍 #기초
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.0
mw41817
Spring(AOP)_01
상단으로

티스토리툴바