spring aop @target 和@within 抛出 IllegalAccessError
spring aop @target and @within throw IllegalAccessError
当运行应用时,抛出IllegalAccessError,应用运行失败
这里使用了demo aop、service、annotation,一个简单的annotation和@Before advice,同时启用@EnableAspectJAutoProxy
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInterceptAnnotation {
}
@Component
@Aspect
public class MethodInterceptAop {
@Before("@target(com.example.demo.aop.MethodInterceptAnnotation)")
public void beforeCheck() {
System.out.println("before check");
}
}
public interface UserService {
String getUserName(int a);
}
@Service
public class UserServiceImpl implements UserService {
@MethodInterceptAnnotation
public String getUserName(int age) {
System.out.println("age:" + age);
return age + "";
}
}
改@target
为@within
再次报错,
但是把@target
改成@annotation
一切正常
这里是部分堆栈跟踪
Caused by: org.springframework.cglib.core.CodeGenerationException: java.lang.IllegalAccessError-->class org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration$EmbeddedTomcat$$EnhancerBySpringCGLIB$$e5c9e457 cannot access its superclass org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration$EmbeddedTomcat
at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:538) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:363) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:582) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.apply(AbstractClassGenerator.java:110) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.apply(AbstractClassGenerator.java:108) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.core.internal.LoadingCache.call(LoadingCache.java:54) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_201]
at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:134) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:319) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:569) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:416) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:57) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:205) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
... 37 common frames omitted
Caused by: java.lang.IllegalAccessError: class org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration$EmbeddedTomcat$$EnhancerBySpringCGLIB$$e5c9e457 cannot access its superclass org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration$EmbeddedTomcat
at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_201]
at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_201]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201]
at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:535) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
... 51 common frames omitted
任何人都知道这段代码有什么问题,在此先感谢。
来自文档:Supported Pointcut Designators
@target: Limits matching to join points (the execution of methods when
using Spring AOP) where the class of the executing object has an
annotation of the given type.
@within: Limits matching to join points within types that have the
given annotation (the execution of methods declared in types with the
given annotation when using Spring AOP).
@target
和 @within
建议类型都适用于 class/type 。
切入点的范围是全局的,当应用程序启动时,它会尝试识别所有带有注释的 classes/types 并干扰不需要的 classes ,这里 EmbeddedTomcat
相关。
要使 @target
和 @within
建议类型起作用,请尝试通过如下添加范围指示符来缩小范围
@Before("@target(com.example.demo.aop.MethodInterceptAnnotation) && within(com.example.demo..*)")
对我来说,缩小范围一直很有效,但我遇到了来自@kriegaex 的 SO where that too did not help. In that case , resolution for your issue is available in this answer。
请仔细阅读答案和评论以了解使用 @annotation
时的区别。总而言之,建议类型 @target
和 @within
在使用时倾向于为所有 classes 创建代理,而不管注释是否存在于 class 级别。
希望这对您有所帮助。
当运行应用时,抛出IllegalAccessError,应用运行失败
这里使用了demo aop、service、annotation,一个简单的annotation和@Before advice,同时启用@EnableAspectJAutoProxy
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInterceptAnnotation {
}
@Component
@Aspect
public class MethodInterceptAop {
@Before("@target(com.example.demo.aop.MethodInterceptAnnotation)")
public void beforeCheck() {
System.out.println("before check");
}
}
public interface UserService {
String getUserName(int a);
}
@Service
public class UserServiceImpl implements UserService {
@MethodInterceptAnnotation
public String getUserName(int age) {
System.out.println("age:" + age);
return age + "";
}
}
改@target
为@within
再次报错,
但是把@target
改成@annotation
一切正常
这里是部分堆栈跟踪
Caused by: org.springframework.cglib.core.CodeGenerationException: java.lang.IllegalAccessError-->class org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration$EmbeddedTomcat$$EnhancerBySpringCGLIB$$e5c9e457 cannot access its superclass org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration$EmbeddedTomcat
at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:538) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:363) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:582) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.apply(AbstractClassGenerator.java:110) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.apply(AbstractClassGenerator.java:108) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.core.internal.LoadingCache.call(LoadingCache.java:54) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_201]
at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:134) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:319) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:569) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:416) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:57) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:205) ~[spring-aop-5.2.4.RELEASE.jar:5.2.4.RELEASE]
... 37 common frames omitted
Caused by: java.lang.IllegalAccessError: class org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration$EmbeddedTomcat$$EnhancerBySpringCGLIB$$e5c9e457 cannot access its superclass org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration$EmbeddedTomcat
at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_201]
at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_201]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201]
at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:535) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
... 51 common frames omitted
任何人都知道这段代码有什么问题,在此先感谢。
来自文档:Supported Pointcut Designators
@target: Limits matching to join points (the execution of methods when using Spring AOP) where the class of the executing object has an annotation of the given type.
@within: Limits matching to join points within types that have the given annotation (the execution of methods declared in types with the given annotation when using Spring AOP).
@target
和 @within
建议类型都适用于 class/type 。
切入点的范围是全局的,当应用程序启动时,它会尝试识别所有带有注释的 classes/types 并干扰不需要的 classes ,这里 EmbeddedTomcat
相关。
要使 @target
和 @within
建议类型起作用,请尝试通过如下添加范围指示符来缩小范围
@Before("@target(com.example.demo.aop.MethodInterceptAnnotation) && within(com.example.demo..*)")
对我来说,缩小范围一直很有效,但我遇到了来自@kriegaex 的 SO
请仔细阅读答案和评论以了解使用 @annotation
时的区别。总而言之,建议类型 @target
和 @within
在使用时倾向于为所有 classes 创建代理,而不管注释是否存在于 class 级别。
希望这对您有所帮助。