PointCut

- execution : 지정한 메서드가 일치하는 곳에서 Aspect 적용.

- within : 특정 타입에 대해서 Aspect 적용.

- bean : 스프링 빈 이름을 사용하여 빈의 메서드에 적용.

- 연산자를 통한 PointCut ( 예시 : @PointCut("executionTest() && withinTest()") )

 

Advice

-Before : 대상 메서드가 호출되기 전에 Advice 수행

-AfterReturning : 대상 메서드가 성공적으로 완료된 후에 Adivce 수행

-AfterThrowing : 대상 메서드가 예외를 던진 후에 Advice 수행

-After : 대상 메서드의 결과에 상관없이 Advice 수행 ( finally와 같이 최종적으로 수행 )

-Around : 대상 메서드를 감싸서 대상 메서드 호출 전과 후에 Advice 수행

 

Introductions

-DeclarParents : 인터페이스로 구현된 클래스를 대상 메서드의 부모로 추가할 수 있는 기능.

 

 

<!--pom.xml-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-aop</artifactId>
	<version>2.4.2</version>
</dependency>
<!--service.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
     <bean id="printCls" class="com.example.aop.PrintCls"></bean>
     <bean id="aspectJTest" class="com.example.aop.AspectJTest"></bean>
</beans>
//DemoApplication.java

@SpringBootApplication
@EnableAspectJAutoProxy
@ImportResource("classpath:service.xml")
public class DemoApplication {
	private static final Logger logger = LoggerFactory.getLogger(DemoApplication.class);

	public static void main(String[] args) {
		ApplicationContext run = SpringApplication.run(DemoApplication.class, args);
		
		PrintCls bean = run.getBean(PrintCls.class);

		logger.info("--------------    bean method start	--------------");
		bean.printExample();
		logger.info("--------------    bean method end	--------------");
		
		logger.info("--------------    bean return method start    --------------");
		bean.returnStr();
		logger.info("--------------    bean return method end    --------------");
		
		logger.info("--------------    bean throw method start    --------------");
		try {
			bean.returnThrow();
		} catch (Exception e) {
		}
		logger.info("--------------    bean throw method end    --------------");
	}
}
//PrintCls.java

package com.example.aop;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PrintCls{
	private static final Logger logger = LoggerFactory.getLogger(PrintCls.class);
	
	public void printExample() {
		logger.info("*** printExample");
	}
	
	public String returnStr() {
		String value = "testReturning";
		logger.info("*** print returning Str" + value );
		return value;
	}
	
	public void returnThrow() throws Exception {
		String msg = "execption test";
		logger.info("*** print throw " + msg);
		throw new Exception(msg);	
	}

}
//DelcarInterface.java

package com.example.aop;

public interface DelcarInterface {
	public void declarInterfaceTest();
}
//DeclarInterfaceImpl.java

package com.example.aop;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DeclarInterfaceImpl implements DelcarInterface {
	private static final Logger logger = LoggerFactory.getLogger(DeclarInterfaceImpl.class);
	
	@Override
	public void declarInterfaceTest() {
		logger.info("/////////////// declarInterfaceTest ///////////////////");
	}
}
//AspectJTest.java

package com.example.aop;

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.DeclareParents;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Aspect
public class AspectJTest {

	private static final Logger logger = LoggerFactory.getLogger(AspectJTest.class);

	//--PointCut--
	@Pointcut("execution(* com.example.aop.PrintCls.*(..))")
	public void executionTest() {
		logger.info("executeTest start");
		logger.info("executeTest end");
	}
	
	@Pointcut("within(com.example.aop.PrintCls)")
	public void withinTest() {
		logger.info("withinTest start");
		logger.info("withinTest end");
	}
	//--PointCut--
	
	//--Before--
	@Before("execution(* com.example.aop.PrintCls.*(..))")
	public void beforeTest() {
		logger.info("before start");
		logger.info("before end");
	}
	
	@Before("executionTest()")
	public void executionAndBefore() {
		logger.info("execution and Before start");
		logger.info("execution and Before end");
	}
	
	@Before("withinTest()")
	public void withinAndBefore() {
		logger.info("within and Before start");
		logger.info("within and Before end");
	}
	//--Before--
	
	
	//--AfterReturning--
	@AfterReturning("execution(* com.example.aop.PrintCls.*(..))")
	public void afterReturningTest() {
		logger.info("afterReturningTest start");
		logger.info("afterReturningTest end");
	}
	
	@AfterReturning("executionTest()")
	public void executionAndAfterReturning() {
		logger.info("execution and afterReturning start");
		logger.info("execution and afterReturning end");
	}
	
	@AfterReturning("withinTest()")
	public void withinAndAfterReturningTest() {
		logger.info("within and afterReturning start");
		logger.info("within and afterReturning end");
	}

	@AfterReturning(
			pointcut="executionTest()",
			returning="retVal")
	public void executionAndReturnValTest(String retVal) {
		logger.info("execution and afterReturning Value start");
		logger.info("Value :" + retVal);
		logger.info("execution and afterReturning Value end");
	}
	
	@AfterReturning(
			pointcut="withinTest()",
			returning="retVal")
	public void withinAndReturnValTest(String retVal) {
		logger.info("within and afterReturning Value start");
		logger.info("Value :" + retVal);
		logger.info("within and afterReturning Value end");
	}
	//--AfterReturning--
	
	//--AfterThrowing--
	 @AfterThrowing("executionTest()")
	 public void executionAndAfterThrowingTest() {
		 logger.info("execution and AfterThrowing start");
		 logger.info("execution and AfterThrowing end");
	 }
	 
	 @AfterThrowing("withinTest()")
	 public void withinAndAfterThrowingTest() {
		 logger.info("within and AfterThrowing start");
		 logger.info("within and AfterThrowing end");
	 }
	 
	 @AfterThrowing(
		        pointcut="executionTest()",
		        throwing="ex")
	 public void executionAndAfterThrowingValTest(Exception ex) {
		 logger.info("execution and AfterThrowing Value start");
		 logger.error(ex.getMessage());
		 logger.info("execution and AfterThorwing Value end");
	 }
	 
	 
	 @AfterThrowing(
		        pointcut="executionTest()",
		        throwing="ex")
	 public void withinAndAfterThrowingValTest(Exception ex) {
		 logger.info("execution and AfterThrowing Value start");
		 logger.error(ex.getMessage());
		 logger.info("execution and AfterThorwing Value end");
	 }
	 //--AfterThrowing--
	 
	 
	 //--After--
	 @After("executionTest()")
	 public void executionAndAfterTest() {
		 logger.info("execution and After start");
		 logger.info("execution and AFter end");
	 }
	 
	 @After("withinTest()")
	 public void withinAndAfterTest() {
		 logger.info("within and after start");
		 logger.info("within and after end");
	 }
	 //--After
	 
	 //--Around
	 @Around("executionTest()")
	 public void executionAndAroundTest(ProceedingJoinPoint  pjp){
		 logger.info("execution and around start");
		 logger.info(pjp.getSignature().getName() + " Before Method Execution");
		 try {
			 pjp.proceed();
		 } catch (Throwable e) {
			 logger.info(pjp.getSignature().getName() + "Throw Method Execution");
		 } finally {
			 // Do Something useful, If you have
		 }
		 logger.info(pjp.getSignature().getName() + " After Method Execution");
		 logger.info("execution and around end");
	 }
	 
	 @Around("withinTest()")
	 public void withinAndAroundTest(ProceedingJoinPoint  pjp) {
		 logger.info("within and around start");
		 logger.info(pjp.getSignature().getName() + " Before Method Execution");
		 try {
			 pjp.proceed();
		 } catch(Throwable e) {
			 logger.info(pjp.getSignature().getName() + "Throw Method Execution");
		 } finally {
			 // Do Something useful, If you have
		 }
		logger.info(pjp.getSignature().getName() + " After Method Execution");

		 logger.info("within and around end");
	 }
	 //--Around--
	 
	 
	 
	 //--Introductions ( DeclarParents )--
	 @DeclareParents(value="com.example.aop.PrintCls", defaultImpl=DeclarInterfaceImpl.class)
	 public static DelcarInterface mixin;

	 @Before("executionTest() && this(dInterface)")
	 public void declarTest(DelcarInterface dInterface) {
		 dInterface.declarInterfaceTest();
	 }
	 //--Introductions ( DeclarParents )--
}