诚心求助 Spring 注入式 AspectJ 切面时 ClassNotFoundException 的问题 - V2EX
Febers
V2EX    Java

诚心求助 Spring 注入式 AspectJ 切面时 ClassNotFoundException 的问题

  •  
  •   Febers Jun 3, 2019 1993 views
    This topic created in 2535 days ago, the information mentioned may be changed or developed.

    楼主最近在学 Spring,按照《 Spring in Action 》上面的运行时注入 AspectJ 切面的 demo 敲,发现了一个目前找不到解决办法的问题,代码运行时提示 找不到引用( Java/Kotlin )、ClassNotFoundException ( XML 文件),Google 了半天,在 StackOverflow 上看到了相似的情况,同样没有找到解决办法,自己也琢磨不出,只能向有经验的 V 友求助

    demo 大致思路:一个表演类“ MyPerformance ”,其中定义方法 perform,也就是切点。一个 AspectJ 类 CriticAspect,定义在同名 aj 文件中,在其中定义通知。表演结束之后打印一段字符串。具体代码如下

    @Component open class MyPerformance: Performance { override fun perform() { println("Start perform") } } 

    AspectJ 文件 CriticAspect.aj

    public aspect CriticAspect { public CriticAspect() { } pointcut performance(): execution(* concert.MyPerformance.perform(..)); after(): performance() { System.out.println("something"); } } 

    下面是 XML 配置文件 concert.xml 。根据书上所说,Spring 不能负责创建 CriticAspect,需要由 AspectJ 运行期创建,因此得为 Spring 获得已经由 AspectJ 创建好的实例的引用。书上的例子采用的是 XML 的方式,通过切面的静态方法 aspectOf 返回实例

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cOntext="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <context:component-scan base-package="concert" /> <aop:aspectj-autoproxy /> <bean class="concert.CriticAspect" factory-method="aspectOf" /> </beans> 

    下面是测试代码

    @RunWith(SpringJUnit4ClassRunner::class) @ContextConfiguration(locatiOns= ["classpath:concert.xml"]) class PerformTest { @Autowired lateinit var performance: Performance @Test fun perform() { performance.perform() } } 

    运行失败,报错信息摘录如下

     ...... 严重: Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@491cc5c9] to prepare test instance [concert.PerformTest@74c79fa2] java.lang.IllegalStateException: Failed to load ApplicationContext ...... Caused by: org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [concert.CriticAspect] for bean with name 'concert.CriticAspect#0' defined in class path resource [concert.xml]; nested exception is java.lang.ClassNotFoundException: concert.CriticAspect ...... Caused by: java.lang.ClassNotFoundException: concert.CriticAspect ...... 

    如果以 JavaConfig 的方式配置,按照 StackOverflow 上一个回答 我找到了 aspectOf 的接口,以下为 Kotlin 代码

    @Configuration @EnableAspectJAutoProxy @ComponentScan open class ConcertConfig { @Bean open fun criticAspect(): CriticAspect = org.aspectj.lang.Aspects.aspectOf(CriticAspect::class.java) } 

    运行之后 IEDA 报错

    Error:(13, 30) Kotlin: Unresolved reference: CriticAspect 

    Java 形式我也试过,一样的报错信息:"找不到引用: CriticAspect"。在 StackOverflow 上看到了相同的问题How to resolve the following AspectJ aspect ClassNotFoundException? ,两个回答都没有解决办法

    除了使用 aj 文件动态织入之外的代码都是正确运行的,包括使用 Spring 支持的 AOP 注解,错误只有在引入了 AspectJ 文件之后才出现。比如将 XML 配置文件中声明 bean 的那行删去,demo 正常工作,将 JavaConfig 中那个 bean 方法去掉其他部分也能正常工作。

    开发环境为 Win10 + IDEA + JDK 11 + Kotlin,感谢你看到这里,希望能得到建设性意见,谢谢。

    Supplement 1    Jun 3, 2019

    并不愿意在这上面花费过多时间和精力,目的还是在于理解 Spring AOP 的知识并完成博客的学习笔记:Spring 学习笔记(三):面向切面 | ReBE

    楼主将不再纠结 AspectJ 的问题,留着日后有空解决吧

    12 replies    2019-06-03 11:44:18 +08:00
    Allianzcortex
        1
    Allianzcortex  
       Jun 3, 2019
    1. 《 Spring In Action 》第五版已经出来,集成了 Spring Boot,并且取消了 AspectJ 这部分内容(专门再搜了下,整本书没有出现 "AspectJ" 这个关键词),楼主考虑换成这个版本的?

    2. 不知道为什么会出现这种情况,已经好久没有看过 XML 配置文件了...我当时用注解实现的 AspectJ 代码在这里 https://github.com/Allianzcortex/LaraForum/blob/master/src/main/java/com/laraforum/authorization/RolesAndPermissionChecker.java#L52,调用时就像 Python @Decorator 一样调用: https://github.com/Allianzcortex/LaraForum/blob/104b16fcd8847aa84bb9f5947d57f8c848fb3e5a/src/main/java/com/laraforum/controller/OtherController.java#L86
    Febers
        2
    Febers  
    OP
       Jun 3, 2019 via Android
    @Allianzcortex 其实我是准备重点学习 Spring Boot,但是绕不过 Spring,所以准备快速过一遍,但是没想到遇到问题了。
    我看了你的代码了,其实我也不喜欢 XML 文件,所以一直用的注解配置,然后也没出问题,直到遇到了 aj 文件。出问题了才用 XML 过一遍好定位原因。
    感谢你的回复。
    Febers
        3
    Febers  
    OP
       Jun 3, 2019 via Android
    整个问题可以概括为: 为什么 Spring 无法识别 aspect 类型的类文件
    Allianzcortex
        4
    Allianzcortex  
       Jun 3, 2019
    @Febers 不知道为什么会有 .aj 这种文件,一开始就是在 .java 里定义切面。官网和博客资料会好很多,那本书太大而全了,真要跑起来还要学 thymeleaf 模板
    Febers
        5
    Febers  
    OP
       Jun 3, 2019 via Android
    @Allianzcortex 对的,我也很无语
    lil460982475
        6
    lil460982475  
       Jun 3, 2019
    以前看过相关概念,但没有实践过。.aj 文件并不是 Java 类,你虽然有这个文件,xml 也定义了,但应该不能直接识别,需要将 .aj 通过专门的编译器编译成 class 文件。

    看下这篇文章,看有没有帮助。https://blog.csdn.net/javazejian/article/details/56267036
    lil460982475
        7
    lil460982475  
       Jun 3, 2019
    对了,spring 你要使用切面技术,并不需要使用 apectj 框架的语法去定义,spring aop 已经能让你使用 java+spring 代码去实现了,没必要
    Febers
        8
    Febers  
    OP
       Jun 3, 2019 via Android
    @lil460982475 对的,目前的进展就到这一步,需要 ajc 编译器,等会查阅相关资料试试
    Febers
        9
    Febers  
    OP
       Jun 3, 2019 via Android
    @lil460982475 应该就是这篇文章所讲:https://m.w3cschool.cn/intellij_idea_doc/intellij_idea_doc-woks2nde.html

    Spring aop 确实已经满足要求,不过我是一边学下边做笔记,遇到这种情况跳不过去
    gz911122
        10
    gz911122  
       Jun 3, 2019
    AspectJ 和 spring 没有什么关系的

    AspectJ 插件装了吗?
    ajc 设置了吗?
    gz911122
        11
    gz911122  
       Jun 3, 2019
    @gz911122 再概括一下,spring aop 和 aspectJ 一毛钱关系也没有
    只不过 spring 借用了 aspectJ 的注解而已
    Febers
        12
    Febers  
    OP
       Jun 3, 2019
    @gz911122 #10 AspectJ 插件一开始就装了。按照[ Mojo's AspectJ Maven Plugin]( https://www.mojohaus.org/aspectj-maven-plugin/usage.html)这个插件设置了 ajc,IDE Compiler 也没问题。但是又遇到问题了,这回是 ajc 的

    Error:ajc: can't find critical required type java.io.Serializable
    Error:ajc: can't find critical required type java.lang.Cloneable

    Google 只找到几条零碎的信息
    About     Help     Advertise     Blog     API     FAQ     Solana     3354 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 95ms UTC 13:06 PVG 21:06 LAX 06:06 JFK 09:06
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86