Search

Spring AOP

Spring AOP

: μŠ€ν”„λ§ ν”„λ ˆμž„μ›Œν¬μ—μ„œ 핡심 λΉ„μ¦ˆλ‹ˆμŠ€ 둜직과 νš‘λ‹¨μ  관심사λ₯Ό λΆ„λ¦¬ν•˜λŠ” κΈ°λŠ₯
Aspect Oriented Programming
Spring AOPλ₯Ό μ‚¬μš©ν•˜λ©΄ μ½”λ“œμ˜ 쀑볡을 쀄이고, 관심사λ₯Ό λͺ¨λ“ˆν™”ν•˜μ—¬ μœ μ§€λ³΄μˆ˜μ„±μ„ ν–₯μƒμ‹œν‚€λ©°, μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 핡심 둜직과 관심사λ₯Ό λΆ„λ¦¬ν•˜λŠ” λ“±μ˜ 이점을 얻을 수 μžˆμŠ΅λ‹ˆλ‹€.
Spring AOPμ—μ„œ μ„œλΉ„μŠ€ λ ˆμ΄μ–΄μ˜ λ©”μ†Œλ“œμ— μ μš©λ˜λŠ” λ‹€μ–‘ν•œ μ–΄λ“œλ°”μ΄μŠ€λ₯Ό μ •μ˜ν•˜μ—¬ λ‘œκΉ… 및 μ˜ˆμ™Έ μ²˜λ¦¬μ™€ 같은 λ‹€μ–‘ν•œ μž‘μ—…μ„ μˆ˜ν–‰ν•©λ‹ˆλ‹€. 이λ₯Ό 톡해 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ λ™μž‘μ„ μΆ”μ ν•˜κ³  λͺ¨λ‹ˆν„°λ§ν•  수 있으며, μ˜ˆμ™Έ 처리λ₯Ό μˆ˜ν–‰ν•˜μ—¬ μ•ˆμ •μ„±μ„ μœ μ§€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

AOP μ£Όμš” μš©μ–΄

μš©μ–΄
μ„€λͺ…
μ–΄λ“œλ°”μ΄μŠ€(Advice)
νš‘λ‹¨ 관심사λ₯Ό μž‘μ„±ν•œ λ©”μ†Œλ“œ
관점 (Aspect)
쑰인 ν¬μΈνŠΈμ™€ ν¬μΈνŠΈμ»·μ„ μ •μ˜ν•œ μ–΄λ“œλ°”μ΄μŠ€λ“€μ„ λͺ¨μ•„놓은 클래슀
쑰인포인트 (Join Point)
μ–΄λ“œλ°”μ΄μŠ€λ₯Ό νƒ€κ²Ÿμ— μ μš©ν•˜λŠ” 타이밍
포인트컷 (Pointcut)
μ–΄λ“œλ°”μ΄μŠ€ 적용 쑰건
νƒ€κ²Ÿ (Target)
μ–΄λ“œλ°”μ΄μŠ€κ°€ μ μš©λ˜λŠ” 클래슀
ν”„λ‘μ‹œ(Proxy), λ¦¬ν”Œλ ‰μ…˜(Reflection)
Spring AOPλŠ” μžλ°” μ–Έμ–΄μ˜ ν”„λ‘μ‹œμ™€ λ¦¬ν”Œλ ‰μ…˜μ„ ν™œμš©ν•˜μ—¬ AOPλ₯Ό κ΅¬ν˜„ν•©λ‹ˆλ‹€.

Spring AOP 적용 방법

1.
μ˜μ‘΄μ„± μ„€μ •
a.
Spring AOP
b.
aspectjrt
c.
aspectjweaver
2.
Aspect 클래슀 μ •μ˜
a.
@EnableAspectJAutoProxy
b.
@Component
c.
@Aspect
3.
포인트컷 μ •μ˜
a.
μ–΄λ“œλ°”μ΄μŠ€ λ©”μ†Œλ“œμ— 포인트컷 ν‘œν˜„μ‹ μ •μ˜
b.
포인트컷 λ©”μ†Œλ“œ μ •μ˜
4.
μ–΄λ“œλ°”μ΄μŠ€ μ •μ˜
a.
JoinPoint
b.
ProceedingJoinPoint

μž‘μ—… μˆœμ„œ

β€’
μ˜μ‘΄μ„± μ„€μ •
β—¦
Spring AOP
β—¦
aspectj
β–ͺ
aspectjrt
β–ͺ
aspectjweaver
β€’
Spring AOP ν™œμ„±ν™”
β€’
λΉ„μ¦ˆλ‹ˆμŠ€ 둜직 μ½”λ“œ μž‘μ„±
β€’
Aspect 클래슀 μ½”λ“œ μž‘μ„±
β€’
포인트컷 μ •μ˜
β€’
μ–΄λ“œλ°”μ΄μŠ€ μ •μ˜

μ˜μ‘΄μ„± μ„€μ •

β€’
pom.xml
<properties> <java-version>1.8</java-version> <org.springframework-version>5.3.10</org.springframework-version> <org.aspectj-version>1.9.7</org.aspectj-version> <!-- μ•„λž˜ λ²„μ „μœΌλ‘œ ν–ˆμ„ λ•Œ, @AfterReturning μ—μ„œ returning 이 계속 null 인 이슈 --> <!-- <org.springframework-version>5.0.7.RELEASE</org.springframework-version> --> <!-- <org.aspectj-version>1.5.4</org.aspectj-version> --> <org.slf4j-version>1.6.6</org.slf4j-version> </properties>
Java
볡사
<!-- Spring AOP --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${org.springframework-version}</version> </dependency> <!-- Aspect --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>${org.aspectj-version}</version> </dependency> <!-- μœ„μ— 이미 μžˆλ‹€. --> <!-- <dependency> --> <!-- <groupId>org.aspectj</groupId> --> <!-- <artifactId>aspectjrt</artifactId> --> <!-- <version>${org.aspectj-version}</version> --> <!-- <scope>runtime</scope> --> <!-- </dependency> --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>${org.aspectj-version}</version> <scope>runtime</scope> </dependency>
XML
볡사

νŒŒλΌλ―Έν„° 좜λ ₯ μ•ˆλ˜λŠ” 이슈

β€’
pom.xml
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <compilerArgs> <arg>-parameters</arg> </compilerArgs> </configuration> </plugin>
XML
볡사
pom.xml μ „μ²΄μ½”λ“œ
β€’
ν”„λ‘œμ νŠΈ μ„€μ •, μ˜μ‘΄μ„± μ„€μ •, ν”ŒλŸ¬κ·ΈμΈ μ„€μ •
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.joeun</groupId> <artifactId>test</artifactId> <name>Spring-AOP</name> <packaging>war</packaging> <version>1.0.0-BUILD-SNAPSHOT</version> <properties> <java-version>1.8</java-version> <org.springframework-version>5.3.10</org.springframework-version> <org.aspectj-version>1.9.7</org.aspectj-version> <org.slf4j-version>1.6.6</org.slf4j-version> </properties> <dependencies> <!-- Spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${org.springframework-version}</version> <exclusions> <!-- Exclude Commons Logging in favor of SLF4j --> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${org.springframework-version}</version> </dependency> <!-- AspectJ --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>${org.aspectj-version}</version> </dependency> <!-- Logging --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${org.slf4j-version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>${org.slf4j-version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${org.slf4j-version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.15</version> <exclusions> <exclusion> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> </exclusion> <exclusion> <groupId>javax.jms</groupId> <artifactId>jms</artifactId> </exclusion> <exclusion> <groupId>com.sun.jdmk</groupId> <artifactId>jmxtools</artifactId> </exclusion> <exclusion> <groupId>com.sun.jmx</groupId> <artifactId>jmxri</artifactId> </exclusion> </exclusions> <scope>runtime</scope> </dependency> <!-- @Inject --> <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency> <!-- Servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- Test --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.7</version> <scope>test</scope> </dependency> <!-- Spring AOP --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${org.springframework-version}</version> </dependency> <!-- AOP --> <!-- μœ„μ— 이미 μžˆλ‹€. --> <!-- <dependency> --> <!-- <groupId>org.aspectj</groupId> --> <!-- <artifactId>aspectjrt</artifactId> --> <!-- <version>${org.aspectj-version}</version> --> <!-- <scope>runtime</scope> --> <!-- </dependency> --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>${org.aspectj-version}</version> <scope>runtime</scope> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.30</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-eclipse-plugin</artifactId> <version>2.9</version> <configuration> <additionalProjectnatures> <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature> </additionalProjectnatures> <additionalBuildcommands> <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand> </additionalBuildcommands> <downloadSources>true</downloadSources> <downloadJavadocs>true</downloadJavadocs> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <compilerArgs> <arg>-parameters</arg> </compilerArgs> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <configuration> <mainClass>org.test.int1.Main</mainClass> </configuration> </plugin> </plugins> </build> </project>
XML
볡사

Spring AOP ν™œμ„±ν™”

β€’
root-context.xml
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
XML
볡사
namespaces μ—μ„œ aop μ²΄ν¬λ°•μŠ€ 지정

λΉ„μ¦ˆλ‹ˆμŠ€ 둜직 μ½”λ“œ μž‘μ„±

β€’
Board.java
β€’
BoardService.java
β€’
BoardServiceImpl.java
β€’
BoardDAO.java
β€’
HomeController.java

Board.java

package com.joeun.test.dto; import java.util.Date; import lombok.Data; @Data public class Board { private int boardNo; private String title; private String writer; private String content; private Date regDate; private Date updDate; public Board() { } public Board(String title, String writer, String content) { this.title = title; this.writer = writer; this.content = content; } }
Java
볡사

BoardService.java

package com.joeun.test.service; import java.util.List; import com.joeun.test.dto.Board; public interface BoardService { // κ²Œμ‹œκΈ€ λͺ©λ‘ public List<Board> list() throws Exception; // κ²Œμ‹œκΈ€ 쑰회 public Board select(int boardNo); // κ²Œμ‹œκΈ€ 등둝 public int insert(Board board) throws Exception; // κ²Œμ‹œκΈ€ μˆ˜μ • public int update(Board board) throws Exception; // κ²Œμ‹œκΈ€ μ‚­μ œ public int delete(int boardNo) throws Exception; }
Java
볡사

BoardServiceImpl.java

package com.joeun.test.service; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.joeun.test.HomeController; import com.joeun.test.dao.BoardDAO; import com.joeun.test.dto.Board; @Service // λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ„ μ²˜λ¦¬ν•˜λŠ” μ„œλΉ„μŠ€ 클래슀둜 빈 등둝 public class BoardServiceImpl implements BoardService { private static final Logger logger = LoggerFactory.getLogger(BoardServiceImpl.class); @Autowired private BoardDAO boardDAO; @Override public List<Board> list() throws Exception { List<Board> boardList = boardDAO.list(); int count = boardList.size(); return boardList; } @Override public Board select(int boardNo) { Board board = boardDAO.select(boardNo); return board; } @Override public int insert(Board board) throws Exception { int result = boardDAO.insert(board); return result; } @Override public int update(Board board) throws Exception { int result = boardDAO.update(board); return result; } @Override public int delete(int boardNo) throws Exception { int result = boardDAO.delete(boardNo); return result; } }
Java
볡사

BoardDAO.java

package com.joeun.test.dao; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Repository; import com.joeun.test.dto.Board; @Repository // 데이터 μ•‘μ„ΈμŠ€ 객체둜 빈 등둝 public class BoardDAO { public List<Board> list() { List<Board> boardList = new ArrayList<Board>(); boardList.add(new Board("제λͺ©1", "μž‘μ„±μž1", "λ‚΄μš©1")); boardList.add(new Board("제λͺ©2", "μž‘μ„±μž2", "λ‚΄μš©2")); boardList.add(new Board("제λͺ©3", "μž‘μ„±μž3", "λ‚΄μš©3")); return boardList; } public Board select(int boardNo) { // Board board = new Board("제λͺ©", "μž‘μ„±μž", "λ‚΄μš©"); Board board = null; return board; } public int insert(Board board) { int result = 0; return result; } public int update(Board board) { int result = 0; return result; } public int delete(int boardNo) { int result = 0; return result; } }
Java
볡사

HomeController.java

package com.joeun.test; import java.text.DateFormat; import java.util.Date; import java.util.List; import java.util.Locale; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.joeun.test.dto.Board; import com.joeun.test.service.BoardService; /** * Handles requests for the application home page. */ @Controller public class HomeController { private static final Logger logger = LoggerFactory.getLogger(HomeController.class); @Autowired private BoardService boardService; /** * Simply selects the home view to render by returning its name. * @throws Exception */ @RequestMapping(value = "/", method = RequestMethod.GET) public String home(Locale locale, Model model) throws Exception { logger.info("Welcome home! The client locale is {}.", locale); Date date = new Date(); DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale); String formattedDate = dateFormat.format(date); model.addAttribute("serverTime", formattedDate ); // κ²Œμ‹œκΈ€ λͺ©λ‘ μš”μ²­ List<Board> boardList = boardService.list(); model.addAttribute("boardList", boardList ); // κ²Œμ‹œκΈ€ 쑰회 μš”μ²­ Board board = boardService.select(10); if( board == null ) logger.info("board null"); model.addAttribute("board", board); // κ²Œμ‹œκΈ€ 등둝 μš”μ²­ Integer result = boardService.insert(board); return "home"; } }
Java
볡사

Aspect 클래슀 μ½”λ“œ μž‘μ„±

package com.joeun.test.common.aop; import java.time.LocalDateTime; import java.util.Arrays; import java.util.List; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.stereotype.Component; import com.joeun.test.dto.Board; @EnableAspectJAutoProxy @Component @Aspect public class LoggingAspect { private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class); /** * μ–΄λ“œ λ°”μ΄μŠ€ μœ ν˜• * - Around * - Before * - After * - AfterReturning * - AfterThrowing */ /** * 포인트컷 ν‘œν˜„μš”μ†Œ * - μ§€μ‹œμž : execution * - λ°˜ν™˜κ°’ * - νŒ¨ν‚€μ§€ * - 클래슀 * - λ©”μ†Œλ“œ * - 인수 */ @Before("execution(* com.joeun.test.service.BoardService*.*(..))") public void before(JoinPoint jp) { // jp.getSignature() : νƒ€κ²Ÿ λ©”μ†Œλ“œμ˜ μ‹œκ·Έμ²˜ 정보(λ°˜ν™˜νƒ€μž… νŒ¨ν‚€μ§€.클래슀.λ©”μ†Œλ“œ) λ°˜ν™˜ // jp.getArgs() : νƒ€κ²Ÿ λ©”μ†Œλ“œμ˜ λ§€κ°œλ³€μˆ˜λ₯Ό λ°˜ν™˜ logger.info("==================================================================="); logger.info("[@Before] #########################################################"); logger.info("target : " + jp.getTarget().toString()); logger.info("signature : " + jp.getSignature()); logger.info("args : " + Arrays.toString(jp.getArgs()) ); // νŒŒλΌλ―Έν„° 좜λ ₯ printParam(jp); logger.info("===================================================================\n"); } @After("execution(* com.joeun.test.service.BoardService*.*(..))") public void after(JoinPoint jp) { logger.info("==================================================================="); logger.info("[@After] ##########################################################"); logger.info("target : " + jp.getTarget().toString()); logger.info("signature : " + jp.getSignature()); logger.info("args : " + Arrays.toString(jp.getArgs()) ); // νŒŒλΌλ―Έν„° 좜λ ₯ printParam(jp); logger.info("===================================================================\n"); } /* * @Around μœ ν˜•μ„ μ μš©ν•˜λ©΄, @After μ–΄λ“œλ°”μ΄μŠ€λŠ” μ‹€ν–‰λ˜μ§€ μ•ŠλŠ”λ‹€. * * ProceedingJoinPoint : μ–΄λ“œλ°”μ΄μŠ€μ—μ„œ λŒ€μƒ λ©”μ„œλ“œμ˜ 싀행을 μ œμ–΄ν•˜κ³  ν˜ΈμΆœν•˜λŠ” 객체 * - proceed() : λŒ€μƒ λ©”μ†Œλ“œ 호좜 */ @Around("execution(* com.joeun.test.service.BoardService*.*(..))") public Object around(ProceedingJoinPoint jp) { logger.info("==================================================================="); logger.info("[@Around] #########################################################"); logger.info("target : " + jp.getTarget().toString()); logger.info("signature : " + jp.getSignature()); logger.info("args : " + Arrays.toString(jp.getArgs()) ); LocalDateTime time = LocalDateTime.now(); logger.info("ν˜„μž¬ μ‹œκ°„ : " + time); Object result = null; try { result = jp.proceed(); if( result != null ) logger.info("λ°˜ν™˜κ°’ : " + result.toString()); } catch (Throwable e) { logger.error("μ˜ˆμ™Έκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€."); e.printStackTrace(); } // After, Around λ₯Ό ν•¨κ»˜ μ‚¬μš©ν•˜λ €λ©΄, Around μ–΄λ“œλ°”μ΄μŠ€ μ—μ„œ After μ–΄λ“œλ°”μ΄μŠ€λ₯Ό ν˜ΈμΆœν•΄μ€€λ‹€. after(jp); logger.info("===================================================================\n"); return result; } // pointcut : 포인트컷 ν‘œν˜„μ‹ // returning : νƒ€κ²Ÿ λ©”μ†Œλ“œμ˜ λ°˜ν™˜κ°’μ„ μ €μž₯ν•˜λŠ” λ§€κ°œλ³€μˆ˜λͺ… 지정 @AfterReturning(pointcut = "execution(* com.joeun.test.service.BoardServiceImpl.*(..))", returning = "result") public Object afterReturning(JoinPoint jp, Object result) { logger.info("==================================================================="); logger.info("[@AfterReturning] #################################################"); logger.info("target : " + jp.getTarget().toString()); logger.info("signature : " + jp.getSignature()); logger.info("args : " + Arrays.toString(jp.getArgs()) ); // νŒŒλΌλ―Έν„° 좜λ ₯ printParam(jp); // λ°˜ν™˜κ°’ 좜λ ₯ if( result != null ) logger.info("λ°˜ν™˜κ°’ : " + result.toString()); logger.info("===================================================================\n"); return result; } @AfterThrowing(pointcut = "execution(* com.joeun.test.service.BoardService*.*(..))", throwing ="exception") public void afterThrowing(JoinPoint jp, Exception exception) { logger.info("==================================================================="); logger.info("[@AfterThrowing] ##################################################"); logger.info("target : " + jp.getTarget().toString()); logger.info("signature : " + jp.getSignature()); logger.info( exception.toString() ); logger.info("===================================================================\n"); } /** * νŒŒλΌλ―Έν„° 좜λ ₯ * @param jp */ public void printParam(JoinPoint jp) { Signature signature = jp.getSignature(); // νƒ€κ²Ÿ λ©”μ†Œλ“œμ˜ νŒŒλΌλ―Έν„° 이름 κ°€μ Έμ˜€κΈ° String[] parameterNames = ((MethodSignature) signature).getParameterNames(); // νƒ€κ²Ÿ λ©”μ†Œλ“œμ˜ 인수 κ°€μ Έμ˜€κΈ° Object[] args = jp.getArgs(); // νŒŒλΌλ―Έν„° 이름과 값을 좜λ ₯ if( parameterNames != null ) for (int i = 0; i < parameterNames.length; i++) { String paramName = parameterNames[i]; Object paramValue = args[i]; logger.info("νŒŒλΌλ―Έν„°λͺ…: " + paramName + ", κ°’: " + paramValue); } } }
Java
볡사

둜그 결과

β€’
BoardService.list()
=================================================================== [@Around] ######################################################### target : com.joeun.test.service.BoardServiceImpl@6c624938 signature : List com.joeun.test.service.BoardService.list() args : [] ν˜„μž¬ μ‹œκ°„ : 2023-10-14T12:02:11.680185900 =================================================================== [@Before] ######################################################### target : com.joeun.test.service.BoardServiceImpl@6c624938 signature : List com.joeun.test.service.BoardService.list() args : [] =================================================================== =================================================================== [@AfterReturning] ################################################# target : com.joeun.test.service.BoardServiceImpl@6c624938 signature : List com.joeun.test.service.BoardService.list() args : [] λ°˜ν™˜κ°’ : [Board(boardNo=0, title=제λͺ©1, writer=μž‘μ„±μž1, content=λ‚΄μš©1, regDate=null, updDate=null), Board(boardNo=0, title=제λͺ©2, writer=μž‘μ„±μž2, content=λ‚΄μš©2, regDate=null, updDate=null), Board(boardNo=0, title=제λͺ©3, writer=μž‘μ„±μž3, content=λ‚΄μš©3, regDate=null, updDate=null)] =================================================================== =================================================================== [@After] ########################################################## target : com.joeun.test.service.BoardServiceImpl@6c624938 signature : List com.joeun.test.service.BoardService.list() args : [] =================================================================== λ°˜ν™˜κ°’ : [Board(boardNo=0, title=제λͺ©1, writer=μž‘μ„±μž1, content=λ‚΄μš©1, regDate=null, updDate=null), Board(boardNo=0, title=제λͺ©2, writer=μž‘μ„±μž2, content=λ‚΄μš©2, regDate=null, updDate=null), Board(boardNo=0, title=제λͺ©3, writer=μž‘μ„±μž3, content=λ‚΄μš©3, regDate=null, updDate=null)] =================================================================== [@After] ########################################################## target : com.joeun.test.service.BoardServiceImpl@6c624938 signature : List com.joeun.test.service.BoardService.list() args : [] =================================================================== ===================================================================
Java
볡사
β€’
BoardService.select(int)
=================================================================== [@Around] ######################################################### target : com.joeun.test.service.BoardServiceImpl@6c624938 signature : Board com.joeun.test.service.BoardService.select(int) args : [10] ν˜„μž¬ μ‹œκ°„ : 2023-10-14T12:02:11.681185800 =================================================================== [@Before] ######################################################### target : com.joeun.test.service.BoardServiceImpl@6c624938 signature : Board com.joeun.test.service.BoardService.select(int) args : [10] νŒŒλΌλ―Έν„°λͺ…: boardNo, κ°’: 10 =================================================================== =================================================================== [@AfterReturning] ################################################# target : com.joeun.test.service.BoardServiceImpl@6c624938 signature : Board com.joeun.test.service.BoardService.select(int) args : [10] νŒŒλΌλ―Έν„°λͺ…: boardNo, κ°’: 10 λ°˜ν™˜κ°’ : Board(boardNo=0, title=제λͺ©, writer=μž‘μ„±μž, content=λ‚΄μš©, regDate=null, updDate=null) =================================================================== =================================================================== [@After] ########################################################## target : com.joeun.test.service.BoardServiceImpl@6c624938 signature : Board com.joeun.test.service.BoardService.select(int) args : [10] νŒŒλΌλ―Έν„°λͺ…: boardNo, κ°’: 10 =================================================================== λ°˜ν™˜κ°’ : Board(boardNo=0, title=제λͺ©, writer=μž‘μ„±μž, content=λ‚΄μš©, regDate=null, updDate=null) =================================================================== [@After] ########################################################## target : com.joeun.test.service.BoardServiceImpl@6c624938 signature : Board com.joeun.test.service.BoardService.select(int) args : [10] νŒŒλΌλ―Έν„°λͺ…: boardNo, κ°’: 10 ===================================================================
Java
볡사
β€’
BoardService.insert(Board)
=================================================================== [@Around] ######################################################### target : com.joeun.test.service.BoardServiceImpl@6c624938 signature : Integer com.joeun.test.service.BoardService.insert(Board) args : [Board(boardNo=0, title=제λͺ©, writer=μž‘μ„±μž, content=λ‚΄μš©, regDate=null, updDate=null)] ν˜„μž¬ μ‹œκ°„ : 2023-10-14T12:02:11.682188500 =================================================================== [@Before] ######################################################### target : com.joeun.test.service.BoardServiceImpl@6c624938 signature : Integer com.joeun.test.service.BoardService.insert(Board) args : [Board(boardNo=0, title=제λͺ©, writer=μž‘μ„±μž, content=λ‚΄μš©, regDate=null, updDate=null)] νŒŒλΌλ―Έν„°λͺ…: board, κ°’: Board(boardNo=0, title=제λͺ©, writer=μž‘μ„±μž, content=λ‚΄μš©, regDate=null, updDate=null) =================================================================== =================================================================== [@AfterReturning] ################################################# target : com.joeun.test.service.BoardServiceImpl@6c624938 signature : Integer com.joeun.test.service.BoardService.insert(Board) args : [Board(boardNo=0, title=제λͺ©, writer=μž‘μ„±μž, content=λ‚΄μš©, regDate=null, updDate=null)] νŒŒλΌλ―Έν„°λͺ…: board, κ°’: Board(boardNo=0, title=제λͺ©, writer=μž‘μ„±μž, content=λ‚΄μš©, regDate=null, updDate=null) λ°˜ν™˜κ°’ : 1 =================================================================== =================================================================== [@After] ########################################################## target : com.joeun.test.service.BoardServiceImpl@6c624938 signature : Integer com.joeun.test.service.BoardService.insert(Board) args : [Board(boardNo=0, title=제λͺ©, writer=μž‘μ„±μž, content=λ‚΄μš©, regDate=null, updDate=null)] νŒŒλΌλ―Έν„°λͺ…: board, κ°’: Board(boardNo=0, title=제λͺ©, writer=μž‘μ„±μž, content=λ‚΄μš©, regDate=null, updDate=null) =================================================================== λ°˜ν™˜κ°’ : 1 =================================================================== [@After] ########################################################## target : com.joeun.test.service.BoardServiceImpl@6c624938 signature : Integer com.joeun.test.service.BoardService.insert(Board) args : [Board(boardNo=0, title=제λͺ©, writer=μž‘μ„±μž, content=λ‚΄μš©, regDate=null, updDate=null)] νŒŒλΌλ―Έν„°λͺ…: board, κ°’: Board(boardNo=0, title=제λͺ©, writer=μž‘μ„±μž, content=λ‚΄μš©, regDate=null, updDate=null) =================================================================== =========================================================
Java
볡사

JoinPoint

Spring AOPμ—μ„œ νƒ€κ²Ÿ λ©”μ†Œλ“œμ˜ 정보와 μ œμ–΄λ₯Ό μ œκ³΅ν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€
μ ‘κ·Ό κ°€λŠ₯ν•œ 정보
β€’
μ‹€ν–‰ 쀑인 λ©”μ†Œλ“œμ˜ μ‹œκ·Έλ‹ˆμ²˜ (λ©”μ†Œλ“œ 이름, 리턴 νƒ€μž… λ“±)
β€’
λ©”μ†Œλ“œμ˜ νŒŒλΌλ―Έν„°
β€’
νƒ€κ²Ÿ 객체 (μ‹€μ œλ‘œ λ©”μ„œλ“œκ°€ ν˜ΈμΆœλ˜λŠ” 객체)
β€’
기타 μ‹€ν–‰ κ΄€λ ¨ 정보
λ©”μ„œλ“œ
μ„€λͺ…
getSignature()
μ‹€ν–‰ 쀑인 λ©”μ„œλ“œμ˜ μ‹œκ·Έλ‹ˆμ²˜ 정보λ₯Ό κ°€μ Έμ˜΅λ‹ˆλ‹€.
getTarget()
μ‹€ν–‰ 쀑인 λ©”μ„œλ“œμ˜ νƒ€κ²Ÿ 객체(μ‹€μ œλ‘œ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λŠ” 객체)λ₯Ό κ°€μ Έμ˜΅λ‹ˆλ‹€.
getArgs()
μ‹€ν–‰ 쀑인 λ©”μ„œλ“œμ˜ 인수(νŒŒλΌλ―Έν„°) 배열을 κ°€μ Έμ˜΅λ‹ˆλ‹€.
toLongString()
JoinPoint에 λŒ€ν•œ μƒμ„Έν•œ λ¬Έμžμ—΄ ν‘œν˜„μ„ λ°˜ν™˜ν•©λ‹ˆλ‹€.
toShortString()
JoinPoint에 λŒ€ν•œ κ°„λž΅ν•œ λ¬Έμžμ—΄ ν‘œν˜„μ„ λ°˜ν™˜ν•©λ‹ˆλ‹€.
getThis()
JoinPointλ₯Ό ν˜ΈμΆœν•œ ν”„λ‘μ‹œ(λŒ€κ°œ λŒ€μƒ 객체)λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
getKind()
JoinPoint의 μ’…λ₯˜(λ©”μ†Œλ“œ 호좜, μƒμ„±μž 호좜 λ“±)λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
getStaticPart()
JoinPoint의 정적 λΆ€λΆ„(μ‹œκ·Έλ‹ˆμ²˜)을 λ°˜ν™˜ν•©λ‹ˆλ‹€.
getSourceLocation()
JoinPoint의 μ†ŒμŠ€ μœ„μΉ˜(λ©”μ†Œλ“œκ°€ μ„ μ–Έλœ μœ„μΉ˜)λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
μ‹œκ·Έλ‹ˆμ²˜ 정보
λ¦¬ν„΄νƒ€μž… νŒ¨ν‚€μ§€.클래슀λͺ….λ©”μ„œλ“œλͺ…(λ§€κ°œλ³€μˆ˜νƒ€μž…1, λ§€κ°œλ³€μˆ˜νƒ€μž…2, ...)
Java
볡사
void com.joeun.test.service.BoardService.insert(Board)
Java
볡사

ProceedingJoinPoint

JoinPoint μΈν„°νŽ˜μ΄μŠ€λ₯Ό μƒμ†ν•œ μΈν„°νŽ˜μ΄μŠ€.
proceed()둜 νƒ€κ²Ÿ λ©”μ†Œλ“œλ₯Ό 직접 ν˜ΈμΆœν•  수 μžˆμ–΄ νƒ€κ²Ÿ λ©”μ†Œλ“œμ— λŒ€ν•œ μ˜ˆμ™Έμ²˜λ¦¬ν•  수 μžˆλ‹€. 주둜 @Around μ–΄λ“œλ°”μ΄μŠ€μ—μ„œ μ‚¬μš©ν•œλ‹€.
@Around("execution(* com.joeun.test.service.BoardService*.*(..))") public void aroundLog(ProceedingJoinPoint jp) { logger.info("==========================================="); logger.info("Service - @Around"); LocalDateTime time = LocalDateTime.now(); logger.info("ν˜„μž¬ μ‹œκ°„ : " + time); try { Object result = jp.proceed(); } catch (Throwable e) { logger.error("μ˜ˆμ™Έκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€."); e.printStackTrace(); } // After, Around λ₯Ό ν•¨κ»˜ μ‚¬μš©ν•˜λ €λ©΄, Around μ–΄λ“œλ°”μ΄μŠ€ μ—μ„œ After μ–΄λ“œλ°”μ΄μŠ€λ₯Ό ν˜ΈμΆœν•΄μ€€λ‹€. endLog(jp); }
Java
볡사

μ–΄λ“œλ°”μ΄μŠ€ μœ ν˜•

β€’
@Around : 호좜 μ „ν›„ 및 μ˜ˆμ™Έ 처리λ₯Ό μˆ˜ν–‰
β€’
@Before : μ „μ²˜λ¦¬ μž‘μ—…μ„ μˆ˜ν–‰
β€’
@After : ν›„μ²˜λ¦¬ μž‘μ—…μ„ μˆ˜ν–‰
β€’
@AfterReturning : λ©”μ†Œλ“œμ˜ λ°˜ν™˜κ°’μ„ 확인
β€’
@AfterThrowing
1.
@Around
β€’
@Around μ–΄λ“œλ°”μ΄μŠ€λŠ” λŒ€μƒ λ©”μ†Œλ“œμ˜ 싀행을 μ™„μ „νžˆ μ œμ–΄ν•˜λ©°, λ©”μ†Œλ“œ 호좜 μ „ν›„ 및 μ˜ˆμ™Έ 처리λ₯Ό μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
β€’
주둜 λŒ€μƒ λ©”μ†Œλ“œ μ‹€ν–‰ 전후에 μΆ”κ°€ μž‘μ—…μ„ μˆ˜ν–‰ν•˜κ±°λ‚˜, λ©”μ†Œλ“œ 싀행을 μ€‘λ‹¨ν•˜κ±°λ‚˜ λ³€κ²½ν•˜λ €λŠ” κ²½μš°μ— μ‚¬μš©λ©λ‹ˆλ‹€.
β€’
ProceedingJoinPoint 객체λ₯Ό μ‚¬μš©ν•˜μ—¬ λ©”μ†Œλ“œ 싀행을 직접 μ œμ–΄ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
2.
@Before
β€’
@Before μ–΄λ“œλ°”μ΄μŠ€λŠ” λŒ€μƒ λ©”μ†Œλ“œμ˜ μ‹€ν–‰ 전에 μ‹€ν–‰λ©λ‹ˆλ‹€.
β€’
주둜 λŒ€μƒ λ©”μ†Œλ“œκ°€ 호좜되기 전에 μ „μ²˜λ¦¬ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.
β€’
예λ₯Ό λ“€μ–΄, μž…λ ₯ λ§€κ°œλ³€μˆ˜λ₯Ό κ²€μ¦ν•˜κ±°λ‚˜ λ‘œκΉ…μ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
3.
@After
β€’
@After μ–΄λ“œλ°”μ΄μŠ€λŠ” λŒ€μƒ λ©”μ†Œλ“œμ˜ μ‹€ν–‰ 후에 μ‹€ν–‰λ©λ‹ˆλ‹€.
β€’
λŒ€μƒ λ©”μ†Œλ“œκ°€ μ˜ˆμ™Έλ₯Ό λ˜μ§€λ”λΌλ„ μ‹€ν–‰λ©λ‹ˆλ‹€.
β€’
주둜 λŒ€μƒ λ©”μ†Œλ“œ μ‹€ν–‰ 후에 ν›„μ²˜λ¦¬ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.
4.
@AfterReturning
β€’
@AfterReturning μ–΄λ“œλ°”μ΄μŠ€λŠ” λŒ€μƒ λ©”μ†Œλ“œκ°€ μ˜ˆμ™Έ 없이 μ‹€ν–‰λ˜κ³  κ²°κ³Όλ₯Ό λ°˜ν™˜ν•œ κ²½μš°μ— μ‹€ν–‰λ©λ‹ˆλ‹€.
β€’
주둜 λŒ€μƒ λ©”μ†Œλ“œμ˜ λ°˜ν™˜κ°’μ„ ν™•μΈν•˜κ³  λ‘œκΉ… λ˜λŠ” 결과에 λ”°λ₯Έ μΆ”κ°€ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.
5.
@AfterThrowing
β€’
@AfterThrowing μ–΄λ“œλ°”μ΄μŠ€λŠ” λŒ€μƒ λ©”μ†Œλ“œμ—μ„œ μ˜ˆμ™Έκ°€ λ°œμƒν•œ κ²½μš°μ— μ‹€ν–‰λ©λ‹ˆλ‹€.
β€’
주둜 μ˜ˆμ™Έ 정보λ₯Ό λ‘œκΉ…ν•˜κ±°λ‚˜ μ˜ˆμ™Έμ— λ”°λ₯Έ 처리λ₯Ό μˆ˜ν–‰ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.

포인트컷 ν‘œν˜„μ‹

Spring AOPμ—μ„œ μ–΄λ–€ λ©”μ„œλ“œλ₯Ό μ• μŠ€νŽ™νŠΈμ— μ μš©ν• μ§€ μ„ νƒν•˜λŠ” 데 μ‚¬μš©λ˜λŠ” ν‘œν˜„μ‹
μ§€μ‹œμž λ°˜ν™˜κ°’ νŒ¨ν‚€μ§€ 클래슀 λ©”μ†Œλ“œ λ§€κ°œλ³€μˆ˜

μ™€μΌλ“œ μΉ΄λ“œ

기호
의미
*
λͺ¨λ“  λ¬Έμžμ—΄(클래슀, λ©”μ†Œλ“œ)을 λŒ€μ²΄ν•˜μ—¬ μ§€μ •ν•©λ‹ˆλ‹€. ex) * com.aloha.spring.*.*(..)
..
λͺ¨λ“  νŒ¨ν‚€μ§€λ‚˜ λͺ¨λ“  λ§€κ°œλ³€μˆ˜λ₯Ό λŒ€μ²΄ν•˜μ—¬ μ§€μ •ν•©λ‹ˆλ‹€.
* com.aloha.spring..*.*(..)
1 - * : λͺ¨λ“  λ°˜ν™˜ νƒ€μž…
2 - com.aloha.spring : ν•΄λ‹Ή νŒ¨ν‚€μ§€ 경둜λ₯Ό 지정
3 - .. : λͺ¨λ“  ν•˜μœ„ νŒ¨ν‚€μ§€λ₯Ό 지정
3 - * : λͺ¨λ“  클래슀λ₯Ό 지정
4 - * : λͺ¨λ“  λ©”μ†Œλ“œλ₯Ό 지정
5 - (..) : λͺ¨λ“  νŒ¨ν‚€μ§€λ‚˜, λ§€κ°œλ³€μˆ˜λ₯Ό 지정

μ§€μ‹œμž

β€’
execution
β€’
within
β€’
args
β€’
this
β€’
target

execution

λ©”μ†Œλ“œ μ‹€ν–‰ μ‹œμ μ„ μ§€μ •ν•©λ‹ˆλ‹€.
execution(* com.aloha.spring..*.*(..) )
Java
볡사

within

νŠΉμ • νŒ¨ν‚€μ§€ λ˜λŠ” νƒ€μž… λ‚΄μ—μ„œ λ©”μ„œλ“œλ₯Ό μ„ νƒν•©λ‹ˆλ‹€.
within(com.aloha.spring.service.*)
Java
볡사

args

νŠΉμ • λ§€κ°œλ³€μˆ˜ νƒ€μž…μ„ κ°–λŠ” λ©”μ„œλ“œλ₯Ό μ„ νƒν•©λ‹ˆλ‹€.
args(java.util.Integer) args(java.util.String) args(com.aloha.spring.dto.Board)
Java
볡사

this

클래슀의 μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œλ₯Ό λŒ€μƒμœΌλ‘œ μ„ νƒν•©λ‹ˆλ‹€.
this(com.aloha.spring.service.BoardService) this(com.aloha.spring.dao.BoardDAO)
Java
볡사

target

클래슀의 νƒ€κ²Ÿ 객체의 λ©”μ„œλ“œλ₯Ό λŒ€μƒμœΌλ‘œ μ„ νƒν•©λ‹ˆλ‹€.
@ALOHA μ½”λ“œ λ‚΄μš© κ²€ν†  ν›„ μ—…λ°μ΄νŠΈ μ˜ˆμ • - this? target?
this(com.aloha.spring.service.BoardServiceImpl) this(com.aloha.spring.dao.BoardDAO)
Java
볡사

λ…Όλ¦¬μ—°μ‚°μž

&& (AND), || (OR), ! (NOT) 논리 연산을 μ§€μ •ν•˜μ—¬ 포인트컷 ν‘œν˜„μ‹μ„ μ§€μ •ν•©λ‹ˆλ‹€.
execution(* com.aloha.spring.service.BoardService*.*(..)) || within(com.aloha.spring.dao)
Java
볡사
execution(public * *(..) ) && within(com.aloha.spring.dao)
Java
볡사
!execution(* com.aloha.spring.service.CommentService*.*(..) )
Java
볡사