IT/SpringFramework

스프링 <aop>네임스페이스를 이용한 AOP적용 실습

주현태 2019. 12. 2. 19:39

매일같이 1뽀모도리 이상의 실습을 프로젝트를 진행하지 않고 있더라도 하도록 하였으니 오늘은 배운것중. aop 네임스페이스를 이용한 aop 등록에 대해 알아보고자 한다.

 

aop 네임스페이스의 실습에 앞서 aop의 정의에 대해 알아보도록 하자. AoP란 Aspect Oriented Programming의 약자로 한국말로는 관점지향 프로그래밍이라는 뜻이다.

 

이렇게 뜻을 풀어놔도 글자 자체가 어려워서 AOP에 대해서 이해하지 못하고 있었는데 가장 와닿는 정의를 발견하여 다음과 같이 적는다.

 

"OOP로는 모듈화 하지 못하는 프로젝트 전체에 산재해 있는 부가기능 소스를  모듈화 한 것"

 

공통된 부가기능으로는 트랜잭션, 성능테스팅, 로그출력등을 들 수 있다.

 

이번 실습에서는 기존에 만들었던 테스트빈인 MyBean클래스의 myTestMethod() 메소드의 출력 전 후로 "myTestMoethod() Before" "myTestMethod() After" 메시지를 출력하는 예제를 수행해 보도록 하겠다.

 

 


실습진행

 

[pom.xml]

pom.xml에 다음과 같이 Dependency를 입력한다. 이와같이 Dependency적용을 안하여서 다음의 링크와 같은 에러에 직면하였었다.

https://honeyinfo7.tistory.com/146

 

스프링 AOP 적용시 에러(MSG : nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWo

AOP 관련하여 실습을 진행중인데 뭔가 에러메시지가 많이 뜬다. 이상하다.. aop네임스페이스를 책에서 처럼 추가하였을 뿐이었는데 무엇이 문제일까.. 일단, 에러메시지를 쭉 살펴보았는데 다음과같이 클래스를 찾..

honeyinfo7.tistory.com

<!-- AspectJ -->
<dependency>
       <groupId>org.aspectj</groupId>
       <artifactId>aspectjweaver</artifactId>
       <version>${org.aspectj-version}</version>
</dependency>

 

 

[MyBean.java]

부가기능이 적용될 타깃 클래스이다.

public class MyBean {
       public String myTestMethod() {
              System.out.println("test");
              return "test";             
       }
}

 

[MyBeanAdvice.java]

타깃 메소드의 전, 후에 특정 문자열이 출력되도록 소스코드를 작성하였다.

package com.copocalypse.www.aop;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class MyBeanAdvice implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("myTestMoethod() Before");
        Object obj = invocation.proceed();
        System.out.println("myTestMethod() After");

        return obj;
    }
}

 

[src/main/resources/config/root-context.xml]

aop 네임스페이스를 이용함으로써, 빈 후처리기의 등록이나 포인트컷 빈을 등록하지 않아도 된다.

<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
              http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
       <bean id="myBean" class="com.copocalypse.www.util.MyBean" />
       <aop:config>
              <aop:pointcut id="beanAdvicePointcut" expression="execution(* *..*.MyBean.myTestMethod(..))"/>
              <aop:advisor advice-ref="myBeanAdvice" pointcut-ref="beanAdvicePointcut"/>
       </aop:config>
       
       
       <bean id="myBeanAdvice" class="com.copocalypse.www.aop.MyBeanAdvice"/>
</beans>

 

 

 


테스트

 

[MyBeanTest.java]

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.context.ContextLoaderListener;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:config/root-context.xml")
public class MyBeanTest {
    @Autowired
    ApplicationContext ac;

    @Test
    public void myTestMethodTest() {    
        MyBean myBean = (MyBean) ac.getBean("myBean");
        assertThat("test", is(myBean.myTestMethod()));
    }
}

 

결과)

 

JUnit 테스트 결과
Console 출력 결과

테스트 결과 기존의 JUnit 테스트는 문제없이 진행되고 AOP 적용으로 인해 myTestMethod() 수행 전, 후에 "myTestMethod() Before", "myTestMethod() After" 문자열이 출력되는 것을 확인하였다. 이로서 실습을 성공적으로 마친다.