【问题标题】:spring aop @target and @within throw IllegalAccessErrorspring aop @target 和 @within throw IllegalAccessError
【发布时间】:2020-05-02 03:53:28
【问题描述】:

应用运行时抛出IllegalAccessError,Application run failed

这里是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$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

任何人都知道这段代码有什么问题,在此先感谢。

【问题讨论】:

  • 你在使用开发工具吗?
  • 是的。 pom.xml中的spring-boot-devtools,有关系吗?

标签: spring-boot spring-aop


【解决方案1】:

来自文档:Supported Pointcut Designators

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

@within:将匹配限制在具有 给定注释(在类型中声明的方法的执行 使用 Spring AOP 时给出注释)。

@target@within 建议类型都适用于 class/type 。

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

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

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

对我来说,缩小范围一直有效,但遇到了 SO questions 也没有帮助。在这种情况下,可以在@kriegaex 的answer 中找到您的问题的解决方案。

请通过答案和 cmets 了解使用 @annotation 时的区别。总而言之,建议类型 @target@within 在使用时倾向于为所有类创建代理,而不管注释是否存在于类级别。

希望这会有所帮助。

【讨论】:

  • 缩小范围并将注释移动到类级别确实有效。@target @within 不能在方法级别使用?
  • @code1234 这些通知类型用于类型级别的注释。它不能用于定位方法注释。为此,您需要使用@annotation
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多