我是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)
项目结构:
为加载时间编织发送的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>
答案 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!