AspectJ不能使用编译时编织



我正在尝试使用AOP做SQL查询分析

下面是@Aspect definition

的代码片段
@Pointcut("(call(* org.springframework.jdbc.core.JdbcTemplate.query*(..)) || call(* org.springframework.jdbc.core.JdbcTemplate.update*(..)))")
public void profileQuery() {
}
@Around("profileQuery()")
public Object profile(ProceedingJoinPoint thisJoinPoint) throws Throwable {
logger.info("profileQuery() aspect Before");
Object pjp= thisJoinPoint.proceed();
logger.info("profileQuery() aspect After");
return pjp;
}

aspectj maven插件的POM片段

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.14.0</version>
<configuration>
<complianceLevel>${java.version}</complianceLevel>
<showWeaveInfo>true</showWeaveInfo>
<verbose>true</verbose>
<Xlint>ignore</Xlint>
<encoding>UTF-8 </encoding>
</configuration>
<dependencies>
</dependencies> 
<executions>
<execution>
<id>compile</id>
<phase>process-classes</phase>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>    
</execution>
</executions>
</plugin>

maven编译器插件的POM代码段

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<fork>true</fork>
<source>${java.version}</source>
<target>${java.version}</target>
<useIncrementalCompilation>false</useIncrementalCompilation>
<excludes>
<exclude>**/*.*</exclude>
</excludes>
</configuration>
</plugin>

我试过使用Eclipse,也试过在Eclipse之外编译使用的命令mvn clean install -Dmaven.test.skip=true

在Tomcat 8.5.83上构建和部署没有问题,api也可以工作,但是方面没有像预期的那样被拦截。

您的POM和代码中有几个问题,我在此pull请求中修复了这些问题,例如:

  • 您在pluginManagement部分配置了AspectJ Maven Plugin,但忘记在单独的plugins部分实际将插件添加到项目中。

  • 您的示例不包含测试基目录。因此,您需要删除目标test-compile,以避免构建错误。

  • 当使用org.codehaus.mojo:aspectj-maven-plugin时,使用complianceLevel是不够的,还需要指定sourcetarget。或者您只是切换到更好的dev.aspectj:aspectj-maven-plugin变体,那么complianceLevel就足够了。

  • 包名aspect不适合本地AspectJ,因为在AspectJ中它是保留关键字。所以我把你的包重命名为aop

  • 你的切入点call(* service.apiInnerService(..))是错误的,你忘记了类名,应该用call(* service.MainService.apiInnerService(..))代替。

  • 本地AspectJ方面不应该有@Component注释,因为这是用于Spring AOP基于代理的方面的。你应该避免春季再次捡起它。

除了这些更改之外,我还从代码中删除了一些cruft,重新格式化了所有内容,并向AppConfig添加了一个main方法,因此我可以轻松地从IDE运行应用程序并验证方面是否有效。但是在你的WAR中应该是一样的。

运行应用程序时,现在我看到:

Before Around :testAspectPointcut
Innerservice
After Around
Success

。,方面正在工作,拦截你的私有方法调用。但是请允许我说,如果您需要将方面应用于私有方法,那么您的应用程序很可能存在设计问题。

此版本有效:

@Aspect
public class ProfileCallAspect {
private static final Logger LOGGER = LogManager.getLogger(ProfileCallAspect.class);

@Pointcut("call(* org.springframework.jdbc.core.JdbcTemplate.query*(..)) || call(* org.springframework.jdbc.core.JdbcTemplate.update*(..))")
public void profileQuery() {
}
@Around("profileQuery()")
public Object profile(ProceedingJoinPoint thisJoinPoint) throws Throwable {
LOGGER.info("ProfileCallAspect() Before");
Object res =  thisJoinPoint.proceed();
LOGGER.info("ProfileCallAspect() After");
return res ;
}
}

在Spring项目中,你不能让它成为@Component,因为"call"但是@Configurable可以工作(通过@EnableSpringConfigured启用,并在依赖项中使用spring方面)。作为Aspect,它可以在没有日志的情况下工作,但如果你想做一些比日志更有用的事情,你可能需要在其中注入依赖项。当然,在proceed()和after()过程中的任何异常不会被记录,如果你想,你应该替换@Around条目:@Before @After, @AfterReturning, @ afterthrow根据你的需要。您还需要在pom.xml中使用aspectj-maven-plugin和spring-aspects作为aspectLibrary进行构建。(或等价于gradle)

我在pom.xml中删除后得到了这个工作。

不是

<pluginManagement> 
<plugins>
<plugin>
</plugin>
</plugins>
</pluginManagement> 

I changed to

<plugins>
<plugin>
</plugin>
</plugins>

实际上,最初的方法是我在pom.xml

中犯的一个错误如果在正确配置后还有其他编织问题,则得一分:在你使用的IDE之外编译项目,如果你从IDE构建项目,将会覆盖AJC (AspectJ编译器),编织可能不会发生

最新更新