I am creating a Spring boot application with Aspects, but it is not working. It is not getting picked up.
I have defined EnableAspectJAutoProxy in a custom configuration class.
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AppConfig {
@Bean
public ModelMapper modelMapper() {
return new ModelMapper();
}
Going through multiple solutions on stack overflow, I found that adding @Component might solve my issue but when I add @Component, my application fails to start.
please find the error below-
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'projectingArgumentResolverBeanPostProcessor' defined in class path resource [org/springframework/data/web/config/ProjectingArgumentResolverRegistrar.class]: BeanPostProcessor before instantiation of bean failed
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:277) ~[spring-context-6.1.4.jar:6.1.4]
at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:805) ~[spring-context-6.1.4.jar:6.1.4]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608) ~[spring-context-6.1.4.jar:6.1.4]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.2.3.jar:3.2.3]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.2.3.jar:3.2.3]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.2.3.jar:3.2.3]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:334) ~[spring-boot-3.2.3.jar:3.2.3]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354) ~[spring-boot-3.2.3.jar:3.2.3]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-3.2.3.jar:3.2.3]
at com.dimensions.inc.personalTrackerbank.PersonalTrackerbankApplication.main(PersonalTrackerbankApplication.java:10) ~[classes/:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': warning no match for this type name: com.dimensions.inc.personalTrackerbank.bankInfoInterface [Xlint:invalidAbsoluteTypeName]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:607) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:409) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1335) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1165) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans(BeanFactoryAdvisorRetrievalHelper.java:91) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findCandidateAdvisors(AbstractAdvisorAutoProxyCreator.java:111) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors(AnnotationAwareAspectJAutoProxyCreator.java:92) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.shouldSkip(AspectJAwareAdvisorAutoProxyCreator.java:101) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessBeforeInstantiation(AbstractAutoProxyCreator.java:280) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:1130) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:1105) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:511) ~[spring-beans-6.1.4.jar:6.1.4]
... 14 common frames omitted
Caused by: java.lang.IllegalArgumentException: warning no match for this type name: com.dimensions.inc.personalTrackerbank.bankInfoInterface [Xlint:invalidAbsoluteTypeName]
at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:319) ~[aspectjweaver-1.9.21.jar:na]
at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:223) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.aspectj.AspectJExpressionPointcut.obtainPointcutExpression(AspectJExpressionPointcut.java:194) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.aspectj.AspectJExpressionPointcut.getClassFilter(AspectJExpressionPointcut.java:173) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:233) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:295) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.support.AopUtils.findAdvisorsThatCanApply(AopUtils.java:327) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply(AbstractAdvisorAutoProxyCreator.java:128) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:97) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:78) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:366) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:318) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:438) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1789) ~[spring-beans-6.1.4.jar:6.1.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600) ~[spring-beans-6.1.4.jar:6.1.4]
My code -
resource file -
@RestController
@RequestMapping("/data")
public class PtbBankResource {
@GetMapping("/ret")
@ValidateUser(headerName = "Authorization")
public ResponseEntity<?> getCall()
{
return ResponseEntity.ok().body("data Successfull");
}
}
custom annotation -
@Component
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ValidateUser {
String headerName() default "";
}
Aspect class -
@Aspect
public class AuthAspect {
private static final Logger logger = LoggerFactory.getLogger(AuthAspect.class);
@Autowired
PtbUtils ptbUtils;
@Around(value = "execution(* *(..)) && @annotation(ValidateUser)")
public Object authValidation(ProceedingJoinPoint joinPoint, ValidateUser validateUser) throws Throwable
{
logger.info("Inside authValidation class");
String headerName = validateUser.headerName().isEmpty() ? HttpHeaders.AUTHORIZATION : validateUser.headerName();
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
logger.info("headerName = " + headerName);
logger.info("request = " + request);
String token = request.getHeader(headerName);
logger.info("token = " + token);
Boolean value = ptbUtils.validateJwtToken(token);
System.out.println("value = " + value);
return joinPoint.proceed();
}
After going through the replies and reading the official documentation extensively, I found that the @annotation value requires the custom annotation's object rather than class.
Ref - https://docs.spring.io/spring-framework/docs/2.5.x/reference/aop.html#aop-ataspectj-around-advice (Heading 6.2.4)
so my Aspect class becomes ->
@Aspect
@Component
public class AuthAspect {
private static final Logger logger = LoggerFactory.getLogger(AuthAspect.class);
@Autowired
PtbUtils ptbUtils;
@Around("@annotation(validateUser)")
public Object authValidation(ProceedingJoinPoint joinPoint, ValidateUser validateUser) throws Throwable
{
logger.info("Inside authValidation class");
String headerName = validateUser.headerName().isEmpty() ? HttpHeaders.AUTHORIZATION : validateUser.headerName();
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
logger.info("headerName = " + headerName);
logger.info("request = " + request);
String token = request.getHeader(headerName);
logger.info("token = " + token);
Boolean value = ptbUtils.validateJwtToken(token);
System.out.println("value = " + value);
return joinPoint.proceed();
}
}
Edit -
The fix initial issue as highlighted in my question, it required removing the @Component tag from @interface.
After removing @Component from @interface and then adding it to the Aspect class, it gave a new error -
error at::0 formal unbound in pointcut
To fix that, the solution provided before "Edit" worked.