2013-04-03 59 views
6

我想在編譯時將一些方面編織成一個成爲WAR的項目。方面建議在同一個項目中的類(儘管在不同的包中)。AspectJ&Maven警告:「在......中定義的建議尚未應用?」

我得到警告:

Advice not applied 

沒有被執行我的方面。這裏是我的設置:

註釋FooAnnotation.java:

package a; 
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
public @interface FooAnnotation {} 

方面FooAdvice.aj:

package a; 
public aspect FooAdvice { 
    private static final Log log = LogFactory.getLog(FooAdvice.class); 

    Object around() : call(@FooAnnotation * *(..)) { 
     log.info(String.format("Testing around")); 
     return proceed(); 
    } 
} 

我也試過註釋:

@Around("call(@FooAnnotation * *(..))") 
public Object checkFoo(ProceedingJoinPoint joinPoint) throws Throwable { 

至於我能告訴我,我的切入點規範是正確的,但由於某種原因,ajc編譯器不玩球。

類FooClass.java:

package b; 
@ApplicationPath("/service") 
@Path("/{param}") 
@Produces("application/json") 
@Provider 
public class FooClass { 

    @POST 
    @PUT 
    @Path("/{context}/{resource}") 
    @FooAnnotation 
    public String updateResource(...) {} 

的pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>zzz.group</groupId> 
    <artifactId>yyy.artifact</artifactId> 
    <version>0.0.1-SNAPSHOT</version> 
    <packaging>war</packaging> 

    <name>yyy.name</name> 

    <properties> 
     <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
     <javaVersion>1.6</javaVersion> 
     <org.aspectj-version>1.7.2</org.aspectj-version> 
    </properties> 

    <dependencies> 
     <dependency> 
      ... stuff ... 
     </dependency> 
     <dependency> 
      <groupId>org.aspectj</groupId> 
      <artifactId>aspectjrt</artifactId> 
      <version>${org.aspectj-version}</version> 
     </dependency> 
    </dependencies> 

    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <version>3.0</version> 
       <configuration> 
        <source>${javaVersion}</source> 
        <target>${javaVersion}</target> 
        <compilerArguments> 
         <endorseddirs>${endorsed.dir}</endorseddirs> 
        </compilerArguments> 
       </configuration> 
      </plugin> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-war-plugin</artifactId> 
       <version>2.1.1</version> 
       <configuration> 
        <failOnMissingWebXml>false</failOnMissingWebXml> 
       </configuration> 
      </plugin> 
      <plugin> 
       <groupId>org.codehaus.mojo</groupId> 
       <artifactId>aspectj-maven-plugin</artifactId> 
       <!-- 
        Have to use version 1.2 since version 1.3 does not appear to work 
        with ITDs 
       --> 
       <version>1.4</version> 
       <dependencies> 
        <!-- 
         You must use Maven 2.0.9 or above or these are ignored (see 
         MNG-2972) 
        --> 
        <dependency> 
         <groupId>org.aspectj</groupId> 
         <artifactId>aspectjrt</artifactId> 
         <version>${org.aspectj-version}</version> 
        </dependency> 
        <dependency> 
         <groupId>org.aspectj</groupId> 
         <artifactId>aspectjtools</artifactId> 
         <version>${org.aspectj-version}</version> 
        </dependency> 
       </dependencies> 
       <executions> 
        <execution> 
         <goals> 
          <goal>compile</goal> 
          <!-- <goal>test-compile</goal> --> 
         </goals> 
        </execution> 
       </executions> 
       <configuration> 
        <outxml>true</outxml> 
        <source>${javaVersion}</source> 
        <target>${javaVersion}</target> 
       </configuration> 
      </plugin> 
     </plugins> 
    </build> 
</project> 

回答

4

啊哈!找到答案在這裏:

aspectj: why advice cannot be applied?

它無關行家。

原因是在我的示例中,該方法是通過間接加載從jax-rs框架內調用的。建議call()想編織調用者,但ajc編譯器無法知道調用者在哪裏。解決方法是建議改變execution()正是如此:

Object around() : execution(@FooAnnotation * *(..)) {...} 

此不同,因爲它編織執行(其中濃縮蘋果汁可以找到)左右,而不是調用者。

完成。

+0

不幸的是,我發現使用'execute()'通知會導致方法被破壞,以至於反射加載器的jax-rs在加載期間拋出VerifyError消息,所以AOP對於jax-rs並不是一個好的選擇網頁服務。 – PaulProgrammer 2013-04-04 17:56:57