🐢 꼬부기 LV.1 | 개념•기초/💧물대포(핵심개념)

AOP - 스프링 부트식 @사용해보기

서화 2026. 1. 27. 21:48

지난시간에는 xml을 통해 포인트컷과 애스펙트를 설정하는 방법을 배웠다 

이제 스프링 부트에서 사용하는 어노테이션을 사용하여 어드바이스를 실행시키고자한다

✔️설정 방법

1. 오토프록시 설정하기

기존 xml에 오토프록시라는것을 추가해준다 이 오토프록시가 추가됨으로 인해서 어노테이션의 사용이 가능해진다

xml에 있던 기존 코드는 주석으로 가려준다 xml에서 주석사용을 권장하지는 않는다

<aop:aspectj-autoproxy/> //AOP 사용을 위한 설정

2. 기존 bean 태그를 어노테이션으로 변경

기존에는 XML의 <bean> 태그를 통해 어드바이스 객체를 스프링 컨테이너에 등록하였다.
이를 어노테이션 기반 설정으로 변경하면, 어드바이스 클래스에 @Component를 적용하여 동일한 역할을 수행할 수 있다.

@Component는 스프링이 해당 클래스를 빈으로 인식하도록 만드는 가장 기본적인 어노테이션으로,
XML의 <bean> 태그를 대체하는 역할을 한다.

한편, 횡단 관심사를 핵심 관심사에 적용하는 행위위빙(Weaving) 이라고 한다.
AOP 관점에서 보면 어드바이스는 횡단 관심사이며,
현재 프로젝트에서 이 횡단 관심사가 적용되는 대상은 서비스(Service) 계층의 메서드이다.

이 때문에 어드바이스 클래스에 @Service 어노테이션을 적용해야한다

xml 설정
<bean class="com.example.biz.common.LogAdvice" id="la" />

어노테이션
@service // 빈태그를 대신한다
public class LogAdvice {
}

3. 포인트컷 설정하기

xml의 설정을 모두 주석처리해주었으니 로그 어드바이스에서 포인트컷을 설정해줘야한다 

기존 XML설정

<aop:pointcut expression="execution(* com.example.biz..*Impl.*(..))" id="aPointcut" />
<aop:pointcut expression="execution(* com.example.biz..*Impl.get*(..))" id="bPointcut" />

@PointCut 정의하기

@Service
public class LogAdvice {
   	//ServiceImpl 계열 메서드를 대상으로 하는 포인트컷 정의
	@Pointcut("execution(* com.example.biz..*Impl.*(..))")
    	@Pointcut("execution(* com.example.biz..*Impl.get*(..)")
    
    	//포인트컷에 이름을 부여하기 위한 메서드 (실행 로직 없음)
	public void aPointCut(){}
    	public void bPointcut() {}
    
	public void printLog() {
		System.out.println("꼬부기님의 로그");
	}
}

4.애스펙트 만들기

애스펙트는 포인트컷과 어드바이스를 합친것이다

기존 xml 설정

<aop:aspect ref="pla">
   	<aop:before method="printLog" pointcut-ref="aPointcut" />
</aop:aspect>

로그 어드바이스에서 @service위에 @Aspect를 설정해준다 그리고  핵심 관심사 위에 @동작시점과 포인트컷의 이름을 적는다

@Aspect는 안적어도 실행시키는데 문제는 없으나 가독성과 공통으로 사용하는 코드를 중요시해야한다는 점에서 적는것이 더 좋다

@Aspect // 애스팩트 설정하기
@Service
public class LogAdvice {
	@Pointcut("execution(* com.example.biz..*Impl.*(..))")
    	@Pointcut("execution(* com.example.biz..*Impl.get*(..)")
        
        public void aPointCut(){}
    	public void bPointcut() {}
        
	@Before("aPointcut()")// 동작시점과 포인트컷이름 작성
	public void printLog() {
		System.out.println("꼬부기님의 로그");
	}
}

바인드 변수를 사용하는 애프터리터닝과 애프터쓰로잉은 설정방법이 살짝 다르다

기존 xml 설정

<aop:aspect ref="ara">
  	<aop:after-returning method="printLog" pointcut-ref="bPointcut" returning="returnObj" />
</aop:aspect>

포인트컷 이름 옆에 바인드 변수로 사용한 이름을 지정해주었다

@AfterReturning 어노테이션을 사용하여 설정할수 있다 이때 포인트컷의 이름과 사용한 바인드변수명을 지정해줘야한다 즉 xml의 설정과 같다 

@Aspect
@Service
public class AfterReturningAdvice {
	@Pointcut("execution(* com.example.biz..*Impl.*(..))")
    	@Pointcut("execution(* com.example.biz..*Impl.get*(..)")
        
        public void aPointCut(){}
    	public void bPointcut() {}
        
	@AfterReturning(pointcut="bPointcut()", returning="returnObj")
    // xml의 설정과 똑같이 사용한 바인드 변수명을 알려줘야한다 
	public void printLog(JoinPoint jp, Object returnObj) {
    }

🛠️포인트컷 분리하여 새로 클래스만들기

현재 코드에는 포인트컷 정의가 중복되어있다 따라서 포인트컷만 관리하는 클래스를 만들어 따로 관리할것이다

포인트컷 커먼이라는 클래스를 만든다 여기에 @Aspect 어노테이션을 설정해주고 포인트컷을 정의한뒤 기존코드에 있던 포인트 컷을 모두 삭제한다

@Aspect
public class PointcutCommon { // 포인트컷만 관리하는 클래스
	@Pointcut("execution(* com.example.biz..*Impl.*(..))")
	public void aPointcut() {}
	
	@Pointcut("execution(* com.example.biz..*Impl.get*(..))")
	public void bPointcut() {}
}

포인트컷만 관리하는 하나의 클래스를 만들었으므로 어드바이스에 클래스의 이름을 추가해 포인트컷이 있는 위치를 알려주어야한다

@Aspect
@Service
public class LogAdvice {	
	@Before("PointcutCommon.aPointcut()")

 

'🐢 꼬부기 LV.1 | 개념•기초 > 💧물대포(핵심개념)' 카테고리의 다른 글

JDBCtemplate 문법  (0) 2026.01.28
JDBC템플릿 구조  (0) 2026.01.28
어드바이스 사용해보기  (0) 2026.01.26
AOP 설정 및 사용  (0) 2026.01.23
AOP 용어 정리  (0) 2026.01.23