spring aop @target 和 @within 抛出 IllegalAccessError [英] spring aop @target and @within throw IllegalAccessError

查看:28
本文介绍了spring aop @target 和 @within 抛出 IllegalAccessError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

应用程序运行时抛出IllegalAccessError,应用程序运行失败

这里是使用的demo aop、service、annotation,一个简单的注解和@Before 通知,同时启用@EnableAspectJAutoProxy

here is demo aop、service、annotation used,a simple annotation and @Before advice,also enable @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 + "";
    }
}

change@target@within 再次出错,但将@target 改为@annotation 一切正常

change@target to @within error again, but change@target to @annotation everything is ok

这里是部分堆栈跟踪

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$3.apply(AbstractClassGenerator.java:110) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:108) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.cglib.core.internal.LoadingCache$2.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

任何人都知道这段代码有什么问题,提前致谢.

anyone know what is wrong with this code, thanks in advance.

推荐答案

来自文档:支持的切入点指示符

@target:限制匹配到连接点(方法的执行当使用 Spring AOP),其中执行对象的类有一个给定类型的注释.

@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:将匹配限制为具有以下类型的连接点给定的注解(在类型中声明的方法的执行使用 Spring AOP 时给出注解).

@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 的.

Both @target and @within advice types are for the class/type .

切入点的范围是全局的,当应用程序启动时,它会尝试使用注释识别所有类/类型并干扰不需要的类,这里与 EmbeddedTomcat 相关.

The scope of the pointcut is global and when the application starts up it tries to identify all the classes/types with annotation and interferes with unwanted classes , here EmbeddedTomcat related.

要使 @target@within 通知类型起作用,请尝试通过添加范围指示符来缩小范围,如下所示

For @target and @within advice types to work , try narrowing the scope by adding a scoping designator as follows

@Before("@target(com.example.demo.aop.MethodInterceptAnnotation) && inside(com.example.demo..*)")

对我来说,缩小范围总是有效的,但遇到过这样的问题,这也无济于事.在这种情况下,您可以在 @kriegaex 的这个答案中解决您的问题.

For me , narrowing the scope have always worked , but have come across SO questions where that too did not help. In that case , resolution for your issue is available in this answer from @kriegaex.

请仔细阅读答案和评论以了解使用 @annotation 时的区别.总而言之,使用通知类型 @target@within 时,倾向于为所有类创建代理,而不管注解是否存在于类级别.

Please go through the answer and comments to understand the difference when @annotation is used. To summarize , advice types @target and @within when used , tends to create proxies for all classes irrespective if the annotation is present or not at class level.

希望这会有所帮助.

这篇关于spring aop @target 和 @within 抛出 IllegalAccessError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆