지난 시간에 Boy.java, Girl.java 를 만들어서 횡단관심사항과 핵심관심사항이 무엇인지를 살펴 보았습니다.
그럼 여기서는 일단 AOP 적용을 위해 Boy.java 만 바꾸어 보도록 하겠습니다.
Spring AOP 를 쉽게 적용하기 위해서는 인터페이스 기반으로 Boy.java 를 변경하는 것이 유리합니다
(굳이 안해줘도 되긴 하지만 많이 귀찮습니다. 인터페이스 만드는 것이 오히려 편합니다. 상세한 내용은 제 AOP 강좌 이후에 스프링 인 액션, 토비의 스프링 등등을 강츄합니다.)
aop002 패키지를 만들었습니다.
IPerson 이라는 인터페이스를 추가했습니다.
public interface IPerson {
void housework();
}
IPerson 을 구현하도록 Boy.java 를 변경했습니다. 그리고 핵심관심사항이 아닌 횡단관심사항을 깡끄리 지웠습니다. 오오.. 이 간결한 코드를 보라.
public class Boy implements IPerson {
public void housework() {
System.out.println("컴퓨터로 게임을 한다.");
}
}
Start.java 를 Spring 프레임워크 기반에서 구동될 수 있도록 변경했습니다.
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Start {
public static void main(String[] args) {
ApplicationContext context = new FileSystemXmlApplicationContext("/src/main/java/aop002/expert.xml");
IPerson romeo = (IPerson)context.getBean("boy");
romeo.housework();
}
}
그리고 expert.xml 을 생성해야 겠죠.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<aop:aspectj-autoproxy />
<bean id="myAspect" class="aop002.MyAspect" />
<bean id="boy" class="aop002.Boy" />
</beans>
오웃 처음 보는 코드도 있고 myAspect 라고 하는 bean 이 설정되어 있습니다.
당황하지 마시고 expert.xml 을 열고 소스코드 하단의 Namespace 탭을 클릭해서 aop 부분을 체크해 주시면 위에 빨간 세줄이 자동으로 완성이 됩니다. 다시 Source 탭으로 돌아와서
<aop:aspectj-autoproxy />
<bean id="myAspect" class="aop002.MyAspect" />
<bean id="boy" class="aop002.Boy" />
이 세 줄을 입력해주시면 되겠죠.
그럼 aop002.MyAspect.java 의 코딩을 보시죠.
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.JoinPoint;
@Aspect
public class MyAspect {
@Before("execution(public void aop002.Boy.housework())")
public void before(JoinPoint joinPoint){
System.out.println("얼굴 인식 확인: 문을 개방하라");
//System.out.println("열쇠로 문을 열고 집에 들어간다.");
}
}
간단하게 처리하기 위해 애너테이션을 사용했습니다.
@Aspect 는 이 클래스는 이제 AOP 에서 사용하도록 하겠다.
@Befor 는 주어진 메소드의 실행 전에 이 메소드를 실행하겠다.
JoinPoint 는 @Before 에서 선언된 메소드 즉 aop002.Boy.housework() 를 의미합니다.
오호 정상 구동된다면 이제 열쇠로 문을 열고 집에 들어가는 것이 아니라 스프링 프레임워크가 사용자를 인식해서 자동으로 문을 열어주게되겠군요.. 오오 최첨단의 세상에 오신 것을 환영합니다.
자자.. 다 입력하셨으면 저장 확인 하시고 Start.java 의 Context Menu > Run As > Java Application
그럼 결과가...
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from file [C:\workspace_spring\ExpertSpring30\src\main\java\aop002\expert.xml]
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@12b7eea: defining beans [org.springframework.aop.config.internalAutoProxyCreator,myAspect,boy]; root of factory hierarchy
얼굴 인식 확인: 문을 개방하라
컴퓨터로 게임을 한다.
이렇게 나오면 얼마나 행복하시겠습니까마는.. ^^;
INFO : org.springframework.context.support.FileSystemXmlApplicationContext - Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@8814e9: startup date [Tue Jan 22 15:27:21 KST 2013]; root of context hierarchy
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from file [C:\workspace_spring\ExpertSpring30\src\main\java\aop002\expert.xml]
INFO : org.springframework.context.annotation.ClassPathBeanDefinitionScanner - JSR-330 'javax.inject.Named' annotation found and supported for component scanning
Exception in thread "main" java.lang.NoClassDefFoundError: org/aspectj/weaver/BCException
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)
중략...
at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:84)
at aop002.Start.main(Start.java:8)
Caused by: java.lang.ClassNotFoundException: org.aspectj.weaver.BCException
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 13 more
이렇게 나온다는 거.. ㅡㅡ;
큰 문제는 아니지만 구글링을 제대로 안 하시면 몇 일 밤을 새고서 "이거였어!!!!" 하면서 긴 한숨이 나오는 에러죠. ^^
저희가 설치했던 STS 에 추가적인 작업을 해주지 않았기에 발생하는 오류인데요.
간단히 조치 하자면 이렇게 하시면 됩니다. 잘 살펴 보시면 프로젝트 폴더 구조에서 pom.xml 파일을 찾으실 수 있는데요.
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Logging -->
위에 부분을 찾아 아래처럼 내용을 추가 후에 저장해 주시고 다시 Start.java 의 Context Menu > Run As > Java Application 해주시면 예쁜 실행 결과를 보실 수 있습니다.
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.11</version>
</dependency>
<!-- Logging -->
STS 를 더 완벽하게 미리 더 셋팅하고 싶으신 분들은 http://erlka.tistory.com/161 를 참조해 보셔도 좋겠군요. 단, 저는 안했습니다. ^^
이번 강좌에 대한 설명 문서는 다음 강좌에 만들도록 하겠습니다.
'강좌 > Spring 3.0' 카테고리의 다른 글
011. AOP 일단 덤벼 보자 - 용어편 (16) | 2013.01.23 |
---|---|
010. AOP 일단 덤벼 보자 - 설명편 (40) | 2013.01.23 |
008. AOP - Aspect? 관점? 핵심관심사항? 횡단관심사항? (27) | 2013.01.22 |
007. 의존성 주입 DI 초급 마무리 (47) | 2013.01.19 |
006. 스프링을 통한 의존성 주입 - @Autowired vs @Resource vs <property> (37) | 2013.01.17 |