AspectJ는 AOP(Aspect Oriented Programming)을 가능케 해주는 Java 라이브러리 입니다.
실제로 현업에서 AspectJ를 많이 쓰고 있는지는 잘 모르겠지만, Spring AOP를 이해하는데 도움이 될 것 같습니다. 동작 원리는 비슷하니까요.
AspectJ는 사실 Proxy와는 다르지만, 기존 코드를 수정하지 않고 추가적인 기능을 만들 수 있다는 점에서는 거의 비슷하다고 볼 수 있습니다.
예제를 한번 보겠습니다. 다음과 같이 간단한 문자열을 출력하는 Target.test() 메쏘드가 있습니다.
package aspectj; public class Target { public void test() { System.out.println("Target.test()"); } }
위의 test() 메쏘드가 호출될 때마다, 또다른 문자열을 출력하고 싶을 때 다음과 같은 @Aspect를 추가할 수 있습니다.
package aspectj; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class LoggingAspect { @Before("execution (* aspectj.Target.test*(..))") public void advice(JoinPoint joinPoint) { System.out.printf("LoggingAspect.advice() called on %s %n", joinPoint); } }
@Before 어노테이션은 target 메쏘드가 실행되기 전에 실행됩니다. execution 뒤에 있는 문자열의 의미는
* : 모든 access modifier (public, private, protected)
aspectj.Target.test*: aspectj.Target클래스 내의 이름이 test로 시작하는 모든 메쏘드
(..): 모든 매개변수에 대해서
위의 advice() 메쏘드는 aspectj.Target 클래스에서 이름이 test로 시작하는 모든 메쏘드 (public, private, proteced 상관없이)가 실행되기 전에 항상 실행됩니다.
아래 링크에서 소스를 받아서 메이븐을 실행하면 다음의 결과를 볼 수 있습니다.
> mvn clean test
Running aspectj.LogginAspectTest
LoggingAspect.advice() called on execution(void aspectj.Target.test())
Target.test()
LoggingAspect.advice() called on execution(void aspectj.Target.test2())
Target.test2()
AspectJ를 사용함에 있어 한가지 주의해야 할 것이 있는데, aspectj-maven-plugin이 compiler-maven-plugin과 호환되지 않는 부분이 있습니다. 이것 때문에 원인을 찾기에 고생을 좀 했네요. complianceLevel을 1.6으로 해주어야 정상적으로 동작합니다.
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<complianceLevel>1.6</complianceLevel>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
전체 소스 코드는 https://github.com/jinwooe/dynamic-proxy-cglib-aspectj-example 에서 받을 수 있습니다
참고 사이트
http://java.dzone.com/articles/power-proxies-java
http://denis-zhdanov.blogspot.kr/2009/08/weaving-with-aspectj.html
댓글 없음:
댓글 쓰기