[英]Spring - AOP: @within Exception: java.lang.IllegalArgumentException: error Type referred to is not an annotation type
I'm new to AOP and AspectJ.我是 AOP 和 AspectJ 的新手。 I'm trying to write a custom logic around a custom annotation with element type TYPE
.我正在尝试围绕元素类型TYPE
的自定义注释编写自定义逻辑。 I also want to use the parameters under my annotation to write a custom logic inside the around method.我还想使用注解下的参数在 around 方法中编写自定义逻辑。 I'm getting the below mentioned error.我收到下面提到的错误。 I tried reading multiple sources, and most of the sources are related to using @annotation
.我尝试阅读多个来源,大多数来源都与使用@annotation
相关。 I'm finding hard to understand the same.我发现很难理解。 Can someone explain, why the following way with @within
didn't work with some clear example?有人可以解释一下,为什么@within
的以下方式不适用于一些明确的例子?
Annotation( Slf4jTrace.java ):注释( Slf4jTrace.java ):
package io.ud.project.falcon.logging;
import io.ud.project.falcon.logging.generator.AbstractLogTraceIdGenerator;
import io.ud.project.falcon.logging.generator.DefaultLogTraceIdGenerator;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Slf4jTrace {
String traceKey() default "traceId";
Class<? extends AbstractLogTraceIdGenerator> traceValueGenerator() default DefaultLogTraceIdGenerator.class;
}
Aspect Component( Slf4jTraceAspect.java ):方面组件( Slf4jTraceAspect.java ):
package io.ud.project.falcon.logging;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
@SuppressWarnings("unused")
@Slf4j
public class Slf4jTraceAspect {
@Pointcut("execution(public * *(..))")
public void publicOperation() {
//Using this pointcut annotation for Around method.
}
@Around(value = "@within(slf4jTrace) && publicOperation()")
public void logTrace(ProceedingJoinPoint joinPoint, Slf4jTrace slf4jTrace) throws Throwable {
//Custom logic that uses slf4jTrace's parameters
joinPoint.proceed();
//Custom logic that uses slf4jTrace's parameters
}
}
Annotated class( Foo.java ):注释类( Foo.java ):
package io.ud.project.falcon.logging;
import io.ud.project.falcon.logging.Slf4jTrace;
@Slf4jTrace(traceKey = "auditID")
public class Foo {
public void doSomething() {
//Something happens here.
}
}
Error on application startup:应用程序启动错误:
, 2021-01-02 22:16:41,340, ERROR [main] o.s.b.SpringApplication.reportFailure(833) | Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'objectMapperConfigurer' defined in springfox.documentation.spring.web.SpringfoxWebMvcConfiguration
: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cache.annotation.ProxyCachingConfiguration': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: error Type referred to is not an annotation type: slf4jTrace
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:497)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205)
at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:238)
at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:709)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:534)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:388)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1234)
at io.ud.project.falcon.FalconApplication.main(FalconServiceApplication.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
I did not try to run your code, but two things I immediately noticed when glancing at it:我没有尝试运行你的代码,但是当我看到它时,我立即注意到了两件事:
BeanCreationException
for internal Spring types often occur if aspect pointcuts are too broad, ie aspects are also woven into (even if not executed in) Spring classes.如果方面切入点太宽,则内部BeanCreationException
类型的 BeanCreationException 经常发生,即方面也被编织到(即使未在其中执行)Spring 类。 In such cases you want to limit the aspect scope by adding something like ... && within(my.package..*)
to your pointcut.在这种情况下,您希望通过添加类似... && within(my.package..*)
类的内容来限制方面 scope 到您的切入点。 Alternatively, if your aspect is in a library potentially running against unknown package names you can exclude the Spring packages or classes causing problems by .within(org.springframework..*)
or whatever package names are applicable in your case.或者,如果您的方面在可能针对未知 package 名称运行的库中,您可以排除 Spring 包或类导致问题的.within(org.springframework..*)
或任何 ZEFE90A8E604A7C8C88D03 名称适用于您的案例7 See also my answer here .另请参阅我的答案。
Your @Around
advice returns void
, ie it will also only match void
methods, which probably is not what you want.您的@Around
建议返回void
,即它也只会匹配void
方法,这可能不是您想要的。 In order to match non-void methods, the advice must return something other than void
, usually just Object
if you want to match any return type.为了匹配非 void 方法,通知必须返回void
以外的内容,如果您想匹配任何返回类型,通常只Object
。 Also make sure that you return the result of proceed()
or whatever other result you want to be returned.还要确保返回proceed()
的结果或您想要返回的任何其他结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.