Spring

[Spring] Annotation AOP VS XML AOP

Dong's Universe 2024. 4. 16. 16:17

- Annotation 방식

import javax.swing.JPanel;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
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;

@Aspect
public class UserAspect {
	
	String pointcut = "execution(* *.*(..))";
	@Before("execution(* *.*(..))")
	 public void before(JoinPoint joinpoint) {
		 System.out.println("애플리케이션을 시작합니다.");
		 System.out.println(joinpoint.getSignature());
	 }
	
	@AfterReturning(pointcut = "execution(* *.*(..))", returning = "data")
	 public void afterReturn(JoinPoint joinPoint, String data) {
	 	System.out.println("애플리케이션 사용을 끝냅니다.");
	 	System.out.println("이건 afterReturn " + data);
	 }
	
	@AfterThrowing(pointcut = "execution(* *.*(..))", throwing = "exception")
	 public void afterThrow(Exception exception) {
	 	System.out.println("애플리케이션에 문제가 생겨 점검합니다.");
	 	System.out.println(exception);
	 }
	
	@After("execution(* *.*(..))")
	 public void after(JoinPoint joinPoint) {
	 	System.out.println("애플리케이션을 상태와 관련없이 종료합니다.");
	 	System.out.println(joinPoint.toShortString());
	 }
	 
	@Around("execution(* *.*(..))")
	 public String around(ProceedingJoinPoint joinpoint) throws Throwable {
		 System.out.println("애플리케이션 시작전 around");
		 String message = (String) joinpoint.proceed();
		 System.out.println("애플리케이션 끝난후 around");
		 
		 return message;
	 }
}

- annotation을 사용한다고 해도 인자를 사용한다면 throwing이라든지 returning이라든지 필요한 인자는 @ 안에 넣어주어야 한다. 

package com.ssafy.hw;

import javax.swing.JPanel;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
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.annotation.Pointcut;

@Aspect
public class UserAspect {
	
	@Pointcut("execution(* *.*(..))")
    private void anyServiceMethod() {}
	
	@Before("anyServiceMethod()")
	 public void before(JoinPoint joinpoint) {
		 System.out.println("애플리케이션을 시작합니다.");
		 System.out.println(joinpoint.getSignature());
	 }
	
	@AfterReturning(pointcut = "anyServiceMethod()", returning = "data")
	 public void afterReturn(JoinPoint joinPoint, String data) {
	 	System.out.println("애플리케이션 사용을 끝냅니다.");
	 	System.out.println("이건 afterReturn " + data);
	 }
	
	@AfterThrowing(pointcut = "anyServiceMethod()", throwing = "exception")
	 public void afterThrow(Exception exception) {
	 	System.out.println("애플리케이션에 문제가 생겨 점검합니다.");
	 	System.out.println(exception);
	 }
	
	@After("anyServiceMethod()")
	 public void after(JoinPoint joinPoint) {
	 	System.out.println("애플리케이션을 상태와 관련없이 종료합니다.");
	 	System.out.println(joinPoint.toShortString());
	 }
	 
	@Around("anyServiceMethod()")
	 public String around(ProceedingJoinPoint joinpoint) throws Throwable {
		 System.out.println("애플리케이션 시작전 around");
		 String message = (String) joinpoint.proceed();
		 System.out.println("애플리케이션 끝난후 around");
		 
		 return message;
	 }
}

 - pointcut의 중복을 줄이고 싶다면 위와 같이 @Pointcut으로 메서드를 묶어서 활용하면 된다.

<?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:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop 
		http://www.springframework.org/schema/aop/spring-aop.xsd">

		<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
		<bean class="com.ssafy.hw.UserAspect" id="userAspect"></bean>
		<bean class="com.ssafy.hw.GeneralUser" id="generalUser"></bean>
		<bean class="com.ssafy.hw.AdminUser" id="adminUser"></bean>
</beans>

 

- XML 방식

import javax.swing.JPanel;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
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;

@Aspect
public class UserAspect {
	
	 public void before(JoinPoint joinpoint) {
		 System.out.println("애플리케이션을 시작합니다.");
		 System.out.println(joinpoint.getSignature());
	 }
	
	 public void afterReturn(JoinPoint joinPoint, String data) {
	 	System.out.println("애플리케이션 사용을 끝냅니다.");
	 	System.out.println("이건 afterReturn " + data);
	 }
	
	 public void afterThrow(Exception exception) {
	 	System.out.println("애플리케이션에 문제가 생겨 점검합니다.");
	 	System.out.println(exception);
	 }
	
	 public void after(JoinPoint joinPoint) {
	 	System.out.println("애플리케이션을 상태와 관련없이 종료합니다.");
	 	System.out.println(joinPoint.toShortString());
	 }
	 
	 public String around(ProceedingJoinPoint joinpoint) throws Throwable {
		 System.out.println("애플리케이션 시작전 around");
		 String message = (String) joinpoint.proceed();
		 System.out.println("애플리케이션 끝난후 around");
		 
		 return message;
	 }
}
<?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:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop 
		http://www.springframework.org/schema/aop/spring-aop.xsd">

		<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
		<bean class="com.ssafy.hw.UserAspect" id="userAspect"></bean>
		<bean class="com.ssafy.hw.GeneralUser" id="generalUser"></bean>
		<bean class="com.ssafy.hw.AdminUser" id="adminUser"></bean>
		
		<aop:config>
			<aop:pointcut expression="execution(* *.use*(..))" id="mypt"/>
			<aop:aspect ref="userAspect">
				<aop:before method="before" pointcut-ref="mypt"/>
				<aop:after-returning method="afterReturn" pointcut-ref="mypt" returning="data"/>
				<aop:after-throwing method="afterThrow" pointcut-ref="mypt" throwing="exception"/>
				<aop:after method="after" pointcut-ref="mypt"/>
				<aop:around method="around" pointcut-ref="mypt"/>
			</aop:aspect>
		</aop:config>
</beans>

위와 같이 하면 된다.