매일같이 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
<!-- 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 테스트는 문제없이 진행되고 AOP 적용으로 인해 myTestMethod() 수행 전, 후에 "myTestMethod() Before", "myTestMethod() After" 문자열이 출력되는 것을 확인하였다. 이로서 실습을 성공적으로 마친다.