I'm trying to do a SQL query profiling using AOP
Below is my snippet from @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;
}
POM snippet for aspectj maven plugin
<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>
POM snippet for maven compiler plugin
<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>
I tried using Eclipse and also tried compiling outside Eclipse
Command used
mvn clean install -Dmaven.test.skip=true
No issues in building and deploying it on Tomcat 8.5.83 , also the APIs are working, but the aspect is not being intercepted as expected.
CodePudding user response:
There are several problems in your POM and code, which I fixed in this pull request, for example:
You configured AspectJ Maven Plugin in the
pluginManagement
section, but forgot to actually add the plugin to the project in a separateplugins
section.Your example does not contain a test base directory. Therefore, you need to remove goal
test-compile
in order to avoid build errors.When using
org.codehaus.mojo:aspectj-maven-plugin
, usingcomplianceLevel
is not enough, you also need to specifysource
andtarget
. Or you simply switch to the betterdev.aspectj:aspectj-maven-plugin
variant, thencomplianceLevel
is enough.Package name
aspect
is not OK for native AspectJ, because in AspectJ it is a reserved keyword. So I renamed your package toaop
.Your pointcut
call(* service.apiInnerService(..))
is wrong, you forgot the class name and should usecall(* service.MainService.apiInnerService(..))
instead.A native AspectJ aspect should not have a
@Component
annotation, because that is used for Spring AOP proxy-based aspects. You should avoid Spring to pick it up a second time.
In addition to these changes, I also removed some cruft from your code, reformatted everything a bit and added a main method to AppConfig
, so I could easily run the applicaion from my IDE and verify that the aspect works. But it should work the same in your WAR.
When running the application, now I see:
Before Around :testAspectPointcut
Innerservice
After Around
Success
I.e., the aspect is working, intercepting your private method call. But allow me to say that if you need to apply aspects to private methods, you most likely have a design problem in your application.
CodePudding user response:
This version works:
@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 ;
}
}
In a Spring project, you can't make it a @Component because of the "call" in the pointcut, but @Configurable works (enabling by @EnableSpringConfigured and with spring-aspects in the dependencies). As Aspect, it works without, but if you want to do something more useful than just logging you may need to inject dependencies in it. Of course, any exception during the proceed() and the "after" will not be logged, if you want that you should replace the @Around by entries: @Before @After, @AfterReturning, @AfterThrowing according to your needs. You also need the build with aspectj-maven-plugin and spring-aspects as aspectLibrary in your pom.xml. (or the equiv. for gradle)
CodePudding user response:
I got this working after removing in pom.xml.
instead of
<pluginManagement>
<plugins>
<plugin>
</plugin>
</plugins>
</pluginManagement>
I changed to
<plugins>
<plugin>
</plugin>
</plugins>
In fact, the initial approach was a mistake I made in pom.xml
One point if any one else having weaving issues even after proper configuration : Compile the project outside the IDE you are using, If you build the project from IDE there will be overrides for AJC (AspectJ compiler) and the weaving might not happen