在示例aspectJ项目中加载时间编织不起作用

时间:2015-02-02 13:13:55

标签: java aop aspectj

我是aspectJ的新手。我试图在基于aop.xml的aspectJ中实现加载时编织样本,但在构建项目时遇到错误。我理解问题是使用aop.xml但无法解决它。请帮忙。

错误:

[URLClassLoader@132c2ad] warning parse definitions failed -- (SAXException) Unknown element while parsing <aspectj> element: pointcut
Unknown element while parsing <aspectj> element: pointcut
org.xml.sax.SAXException: Unknown element while parsing <aspectj> element: pointcut
at org.aspectj.weaver.loadtime.definition.DocumentParser.startElement(DocumentParser.java:224)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:182)

项目结构:

enter image description here

为加载时间编织发送的VM参数:

-javaagent:{JAR PATH}\aspectj-weaver.jar
Specification-Version: 1.6.8

Main.java

package main.java.aop.main;
import main.java.aop.sample.HelloWorld;
public class Main {
    public static void main(String[] args) {
        System.out.println("<---------- HELLO WORLD example ---------->");
        HelloWorld.say("hi");
        HelloWorld.sayToPerson("hello", "joe");
  }
 }

HelloWorld.java

package main.java.aop.sample;
 public class HelloWorld {
    public static void say(String message) {
        System.out.println("HelloWorld - message: " + message);
}
    public static void sayToPerson(String message, String name) {
        System.out.println("HelloWorld - name: " + name + ", message: " + message);
}
}

HelloWorldAspect:

 package main.java.aop.sample;
 public aspect HelloWorldAspect {
    protected pointcut helloWorld();
    before() : helloWorld() {
        System.out.println("Applying HelloWorldAspect - executing callBefore() - Good day!");
}
    after() : helloWorld() {
        System.out.println("Applying HelloWorldAspect - executing callAfter() - Thankyou!");
}
}

aop.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
    <aspects>
        <aspect name="main.java.aop.sample.HelloWorldAspect">           
            <pointcut name="helloWorld" expression="execution(public static void HelloWorld.say*(..))"/>
        </aspect>
    </aspects>
</aspectj>

的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>com.test</groupId>
<artifactId>TestAspectJXml</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>TestAspectJXml</name>
<dependencies>                            
<dependency>                    
<groupId>org.aspectj</groupId>    
<artifactId>aspectjrt</artifactId>
<version>1.8.2</version>          
</dependency>                         
</dependencies> 
<build>     
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>            
<artifactId>aspectj-maven-plugin</artifactId>        
<configuration>
<complianceLevel>1.6</complianceLevel>
<source>1.6</source>
<target>1.6</target>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>   
</plugin>
<plugin> 
<groupId>org.codehaus.mojo</groupId>         
<artifactId>exec-maven-plugin</artifactId>           
<executions>                                         
<execution>                                      
<goals>                                      
<goal>java</goal>                        
</goals>                                     
</execution>                                     
</executions>                                        
<configuration>                                      
<mainClass>main.java.aop.main.Main</mainClass>
</configuration>                                  
</plugin>
</plugins>

    

1 个答案:

答案 0 :(得分:0)

我现在忽略了maven片段,还有一些我们需要用代码排序的其他问题。如果我们解决这些问题,也许maven的事情也会奏效。

XML(通常)用于通过定义具体方面来填充抽象方面的抽象切入点的切入点。您目前没有抽象方面或抽象切入点。一个抽象切入点是AspectJ的一个指示,即某人将要“稍后填写”(所以类似于抽象方法 - 你可以使用它,但你的系统只有在有人提供实现时才能工作)。所以我们将方面改为:

package main.java.aop.sample;
public abstract aspect HelloWorldAspect {
    protected abstract pointcut helloWorld();
    before() : helloWorld() {
        System.out.println("Applying HelloWorldAspect - executing callBefore() - Good day!");
    }
    after() : helloWorld() {
        System.out.println("Applying HelloWorldAspect - executing callAfter() - Thankyou!");
}
}

请注意,切入点是抽象的,因此类型声明也是抽象的(就像你有抽象方法一样)。

现在我们在XML中提供一个具体的子方面,需要像这样阅读:

<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
    <aspects>
        <concrete-aspect name="Foo" extends="main.java.aop.sample.HelloWorldAspect">
            <pointcut name="helloWorld" expression="execution(public static void *..HelloWorld.say*(..))"/>
        </concrete-aspect>
    </aspects>
</aspectj>

而不是<aspect>我正在使用<concrete-aspect><aspect>用于列出已完成的“完整”方面,无需进一步自定义(如填充切入点)。 <aspect>代码不支持<pointcut>子元素,但<concrete-aspect>支持{/ 1}}。

我们可以在代码中定义具体方面,如下所示:

aspect Foo extends HelloWorldAspect {
  pointcut helloWorld(): execution(public static void *..HelloWorld.say*(..));
}

但是你想利用在XML中定义它,这也很好 - 我只是提供它进行比较。所以XML说“这个方面是HelloWorldAspect的具体版本,要使用的切入点是我的执行切入点”。

另请注意,我更改了执行切入点。之前已阅读HelloWorld.say* - 我将其更改为*..HelloWorld.say*,因为HelloWorld位于包中。

通过这些更改,我现在运行它:

<---------- HELLO WORLD example ---------->
Applying HelloWorldAspect - executing callBefore() - Good day!
HelloWorld - message: hi
Applying HelloWorldAspect - executing callAfter() - Thankyou!
Applying HelloWorldAspect - executing callBefore() - Good day!
HelloWorld - name: joe, message: hello
Applying HelloWorldAspect - executing callAfter() - Thankyou!
相关问题