java AspectJ不支持编译时编织

tuwxkamq  于 2022-12-21  发布在  Java
关注(0)|答案(3)|浏览(150)

我正在尝试使用AOP进行SQL查询分析
以下是我在@Aspect defenition上的片段

@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也在工作,但方面未按预期拦截。

busg9geu

busg9geu1#

POM和代码中有几个问题,我在this pull request中修复了这些问题,例如:

  • 您在pluginManagement部分中配置了AspectJ Maven插件,但是忘记了在单独的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代理的方面的,应该避免Spring第二次使用它。

除了这些修改之外,我还从代码中删除了一些内容,稍微重新格式化了所有内容,并向AppConfig添加了一个main方法,这样我就可以轻松地从IDE运行应用程序并验证方面是否工作正常。
运行应用程序时,现在我看到:

Before Around :testAspectPointcut
Innerservice
After Around
Success

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

oymdgrw7

oymdgrw72#

此版本适用于:

@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项目中,由于切入点中的“call”,您不能将其设置为@Component,但是@Configurable可以工作(通过@EnableSpringConfigured启用,并在依赖项中使用spring-aspects)。作为Aspect,它不需要,但是如果你想做一些比记录更有用的事情,你可能需要在其中注入依赖项。当然,proceed()和“after”期间的任何异常都不会被记录,如果您希望将@Around替换为以下条目:@Before @After,@AfterReturning,@AfterThrowing根据您的需要而定。您还需要在pom.xml中使用aspectj-maven-plugin和spring-aspections作为aspectLibrary进行构建(或等同于gradle)。

3htmauhk

3htmauhk3#

我得到这个工作后,在pom.xml中删除.
代替

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

我换了

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

实际上,最初的方法是我在pom.xml中犯的一个错误
如果任何其他设备即使在正确配置后仍存在编织问题,则需要指出一点:在您正在使用的IDE外部编译项目。如果您从IDE生成项目,则将重写AJC(AspectJ编译器),并且可能不会发生编织

相关问题