우와한 개발자

[Spring] AOP 적용 – XML 방식 (aop:config, aop:aspect, aop:pointcut, aop:advice 등)

by 우와한개발자

[ AOP 적용 - XML 방식 ]

용어 쉬운 설명 예시
Aspect 부가 기능을 모듈화한 클래스 MemberLog
Advice 부가 기능 메서드 MemberLog.logBefore()
Target 핵심 기능을 가진 클래스 MemberService
JoinPoint Advice를 적용할 수 있는 모든 시점(Spring AOP는 메서드 실행 지점) join(), login(), update() 실행 시점 전부
Pointcut JoinPoint 중 Advice를 실제 적용할 위치를 선별하는 표현식 execution(* MemberService.join(..))
Proxy Target을 감싸 Advice를 대신 실행하는 클래스 MemberService$$Proxy
Weaving Pointcut 기준으로 Target에 Advice를 결합하는 과정 join() 호출 시 logBefore()가 자동 실행

 

1. AOP 설정

  • aop 네임스페이스 추가 필요
  • <aop:config> 태그 안에 AOP 설정을 작성함
  • Aspect로 사용할 클래스를 반드시 Bean으로 먼저 등록해야 함
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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">

    <!-- 1. Aspect로 사용할 클래스를 Bean으로 등록 -->
    <bean id="memberLog" class="com.example.myapp.MemberLog"/>

    <!-- 2. AOP 설정 -->
    <aop:config>
        <aop:pointcut .../>
        <aop:aspect ref="memberLog">
            <aop:before .../>
        </aop:aspect>
    </aop:config>

</beans>

 

2. AOP 적용 태그

태그 설명
<aop:config> AOP 설정의 최상위 태그
<aop:aspect> Aspect 선언. ref로 Bean 지정
<aop:pointcut> Pointcut 표현식 정의
<aop:before> Before Advice 적용
<aop:after> After Advice 적용
<aop:after-returning> After Returning Advice 적용
<aop:after-throwing> After Throwing Advice 적용
<aop:around> Around Advice 적용

 

1) <aop:config>

  • AOP 설정의 최상위 태그. 모든 AOP 설정은 이 태그 안에 작성함

 

2) <aop:aspect>

  • Aspect로 사용할 Bean을 지정함
<aop:aspect id="logAspect" ref="memberLog" order="1">
    ...
</aop:aspect>
속성 설명
ref Aspect로 사용할 Bean id 지정 (필수)
id Aspect 식별자
order 여러 Aspect가 있을 때 실행 순서 지정

 

3) <aop:pointcut>

  • Advice를 적용할 대상을 표현식으로 정의함
속성 설명
id Pointcut 식별자. Advice에서 pointcut-ref로 참조 (필수)
expression Pointcut 표현식 (필수)
<aop:pointcut id="memberPointcut"
    expression="execution(* com.example.myapp.MemberService.*(..))"/>

 

4) <aop:before> / <aop:after>

  • Before / After Advice 적용
   
속성 설명
method Aspect 클래스에서 실행할 메서드명 (필수값. 메서드명 그대로 작성!)
pointcut-ref 적용할 Pointcut id 참조
pointcut Pointcut 표현식 직접 작성
<aop:before method="logBefore" pointcut-ref="memberPointcut"/>
<aop:after method="logAfter" pointcut-ref="memberPointcut"/>

 

5) <aop:after-returning>

  • 메서드가 정상적으로 반환된 후 실행
속성 설몀
method 실행할 메서드명 (필수)
pointcut-ref 적용할 Pointcut id 참조
returning 반환값을 받을 파라미터명
<aop:after-returning method="logReturn"
    pointcut-ref="memberPointcut"
    returning="result"/>
public void logReturn(Object result) {
    System.out.println("반환값 : " + result);
}

 

6) <aop:after-throwing>

  • 메서드에서 예외가 발생했을 때 실행
속성 설명
method 실행할 메서드명 (필수)
pointcut-ref 적용할 Pointcut id 참조
throwing 발생한 예외를 받을 파라미터명
<aop:after-throwing method="logException"
    pointcut-ref="memberPointcut"
    throwing="ex"/>
public void logException(Exception ex) {
    System.out.println("예외 발생 : " + ex.getMessage());
}

 

7) <aop:around>

  • 메서드 실행 전후를 모두 감쌈.
  • Target 메서드의 실행 시기, 방법, 실행 여부까지 결정
속성 설명
method 실행할 메서드명 (필수)
pointcut-ref 적용할 Pointcut id 참조
<aop:around method="logAround" pointcut-ref="memberPointcut"/>
public Object logAround(ProceedingJoinPoint pjp) throws Throwable {
    System.out.println("실행 전");
    Object result = pjp.proceed(); // Target 메서드 실행
    System.out.println("실행 후");
    return result;
}

 

3. 태그 작성 순서

1) <aop:config> 안에서의 순서

순서 태그 설명
1 <aop:pointcut> 전역 Pointcut 선언(여러 Aspect에서 공통으로 재사용 가능
2 <aop:advisor> 트랜잭션 등 스프링이 제공하는 Advice 적용
3 <aop:aspect> 일반 Aspect 선언

 

❓ <aop:advisor> vs <aop:aspect> 비교
구분 <aop:advisor>  <aop:aspect>
사용 대상 일반 POJO 클래스 (우리가 직접 만든 Aspect) 스프링이 제공하는 Advice (트랜잭션 등)
주로 사용할 때 로그, 보안 등 커스텀 부가기능 트랜잭션 관리
예시 ref="memberLog" advice-ref="txAdvice"
<aop:config>
    <aop:pointcut id="txPointcut"
        expression="execution(* com.example.myapp.service.*.*(..))"/>

    <!-- 스프링 트랜잭션 Advice 적용 -->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>

    <!-- 직접 만든 Aspect 적용 -->
    <aop:aspect ref="memberLog">
        <aop:before method="logBefore" pointcut-ref="txPointcut"/>
    </aop:aspect>
</aop:config>

 

2) <aop:aspect> 안에서의 순서

순서 태그 설명
1 <aop:pointcut> 지역 Pointcut 선언 (해당 Aspect 안에서만 사용 가능)
2 <aop:before> / <aop:after> 등 Advice 적용

 

전체 코드

더보기
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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">

    <!-- 1. Aspect로 사용할 클래스를 Bean으로 등록 -->
    <bean id="memberLog" class="com.example.myapp.MemberLog"/>

    <aop:config>
        <!-- 2. 전역 Pointcut 선언 -->
        <aop:pointcut id="memberPointcut"
            expression="execution(* com.example.myapp.MemberService.*(..))"/>

        <!-- 3. Aspect 선언 -->
        <aop:aspect ref="memberLog">
            <!-- 4. Advice 적용 -->
            <aop:before method="logBefore" pointcut-ref="memberPointcut"/>
            <aop:after method="logAfter" pointcut-ref="memberPointcut"/>
        </aop:aspect>
    </aop:config>

</beans>
// Aspect 클래스 (부가기능 구현)
public class MemberLog {

    public void logBefore() {
        System.out.println("메서드 실행 전 로그");
    }

    public void logAfter() {

블로그의 정보

우와한개발자 님의 블로그

우와한개발자

활동하기