3

I am creating a custom annotation NullCheck for method parameter to check value is null or not hello(@NullCheck String text), but I am not able to invoke Aspect around the Annotation.

Main Class

package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.EnableAspectJAutoProxy; @SpringBootApplication @EnableAutoConfiguration @EnableAspectJAutoProxy public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } 

Controller class, just invoking an aspect for POC, not returning anything

package com.example.demo; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/") class HelloController { @GetMapping public void hello() { hello("hi"); } private void hello(@NullCheck String text) { System.out.println(text); } } 

Annotation

package com.example.demo; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Documented @Retention(RUNTIME) @Target(ElementType.PARAMETER) public @interface NullCheck { } 

Aspect

package com.example.demo; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; @Aspect @Component public class NullCheckAspect { 

this is working

@Before("@annotation(org.springframework.web.bind.annotation.GetMapping)") 

but this is not

@Before("@annotation(com.example.demo.NullCheck)") public void beforeAdvice(JoinPoint joinPoint) { System.out.println("Before method:" + joinPoint.getSignature()); } } 

build.gradle

buildscript { ext { springBootVersion = '2.1.2.RELEASE' } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: 'java' apply plugin: 'idea' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '1.8' idea { module { // if you hate browsing Javadoc downloadJavadoc = true // and love reading sources :) downloadSources = true } } bootJar { launchScript() } repositories { mavenCentral() jcenter() } bootJar { launchScript() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.boot:spring-boot-starter-aop' implementation 'org.springframework.boot:spring-boot-starter-web' runtimeOnly 'org.springframework.boot:spring-boot-devtools' } 

what am I missing?

1

2 Answers 2

0

As per my understanding and after doing some search on google, you can get method parameter and its value with particular annotation with following code:

package com.example.demo; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; @Component @Aspect public class NullCheckAspect { @Around("execution(* com.example.demo.HelloController.nullChecker(String))") public Object around(ProceedingJoinPoint pJoinPoint) throws Throwable { Object[] args = pJoinPoint.getArgs(); Method method = MethodSignature.class.cast(pJoinPoint.getSignature()).getMethod(); Annotation[][] parametersAnnotations = method.getParameterAnnotations(); Map<String, Object> annotatedParameters = new HashMap<>(); int i = 0; for(Annotation[] parameters : parametersAnnotations) { Object arg = args[i]; String name = method.getParameters()[i++].getDeclaringExecutable().getName(); for(Annotation parameter: parameters) { if ((parameter instanceof NullCheck)) { System.out.println("Found the null checker annotation with name: " + name); System.out.println("Found the null checker annotation with arg: " + arg); annotatedParameters.put(name, arg); } } } System.out.println(annotatedParameters); return pJoinPoint.proceed(args); } } 

And with the interface annotation:

package com.example.demo; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.Target; import org.springframework.stereotype.Component; @Component @Retention(RUNTIME) @Target(ElementType.PARAMETER) public @interface NullCheck { } 

More details about my code you can check it at my github repository, I have created spring boot demo version and pushed it for you at https://github.com/krishnaiitd/learningJava/blob/master/springBoot/gs-spring-boot/src/main/java/com/example/demo/HelloController.java

This also include other type of aspects like tracking the time of a particular methods.

Hope this will help you to get the basic understanding of @Aspect in Spring boot.

Sign up to request clarification or add additional context in comments.

5 Comments

Hi @krishna, Thanks for response, is your code compiling fine? I tried same and here @Around("execution(* hello.HelloController.nullChecker(String))") it's saying java.lang.IllegalArgumentException: warning no match for this type name: hello.HelloController [Xlint:invalidAbsoluteTypeName] so I tried with @Around("execution(* hello.HelloController.nullChecker(String))") and its saying java.lang.IllegalArgumentException: Pointcut is not well-formed: expecting 'name pattern' at character position 43 execution(* @com.example.demo.NullChecker())
@shrikant.sharma As such there is no com.example.demo.NullChecker in my code. In Intellj or eclipses, please run main method of the class Application , I have attached screenshot of compilation in github. One more thing, you should only compile from gs-spring-boot directory.
Hi @krishna, my bad, I forgot to add the package in the snippet, every class is in "com.example.demo" package, I have updated package in question as well.
@shrikant.sharma I have added the steps to run the code which I have provided you on github, please check these steps at: github.com/krishnaiitd/learningJava/tree/master/springBoot/…
@shrikant.sharma I have the provided code with package name as per your snippet, hope you are able to run it and will verify it asap.
0

I don't know why it is as it is but I had the same issue. This is can be solved easily by using Pointcuts, for example:

@Before("nulllCheckAnnotation()") public void beforeAdvice(JoinPoint joinPoint) { System.out.println("Before method:" + joinPoint.getSignature()); } } @Pointcut("@annotation(com.example.demo.NullCheck)") private void nulllCheckAnnotation() { } 

Read more about pointcuts here if you interested: https://www.baeldung.com/spring-aop-pointcut-tutorial

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.