【问题标题】:AspectJ AOP and Spring togetherAspectJ AOP 和 Spring 在一起
【发布时间】:2013-03-24 14:49:11
【问题描述】:

我想同时使用 AspectJ AOP 和 Spring(用于 DI),但出现以下异常:

org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class

我使用 IntelliJ IDEA 12 Ultimate IDE。
以下是重现错误的示例步骤。

1:信息界面:

package org.example.bugs.bug;

public interface Info {
    public void info();
}

2:接口实现:

package org.example.bugs.bug;

public class Informer implements Info {

    @Override
    public void info() {
        System.out.println("Some info from Informer!");
    }
}

3:方面:

package org.example.bugs.bug;

public aspect InfoAspect {

    public InfoAspect() {}

    pointcut info() : execution(* org.example.bugs.bug.Informer.info(..));

    after() returning() : info() {
        System.out.println("Information confirmed by InfoAspect!");
    }

}

4:spring-config.xml 文件:

<?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: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/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <aop:aspectj-autoproxy />

    <bean id="informer"
          class="org.example.bugs.bug.Informer"/>

    <bean class="org.example.bugs.bug.InfoAspect"
          factory-method="aspectOf"/>

</beans>

5:我在以下 Main 类中运行所有内容:

package org.example.bugs.bug;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("org/example/bugs/bug/spring-config.xml");
        Info i = (Info) context.getBean("informer");
        i.info();
    }
}

...我得到错误:

2013-03-24 15:46:10 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@f81843: startup date [Sun Mar 24 15:46:10 CET 2013]; root of context hierarchy
2013-03-24 15:46:10 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [org/example/bugs/bug/spring-config.xml]
2013-03-24 15:46:10 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@13ad085: defining beans [org.springframework.aop.config.internalAutoProxyCreator,informer,org.example.bugs.bug.InfoAspect#0]; root of factory hierarchy
2013-03-24 15:46:10 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@13ad085: defining beans [org.springframework.aop.config.internalAutoProxyCreator,informer,org.example.bugs.bug.InfoAspect#0]; root of factory hierarchy
Exception in thread "main" org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [org.example.bugs.bug.InfoAspect] for bean with name 'org.example.bugs.bug.InfoAspect#0' defined in class path resource [org/example/bugs/bug/spring-config.xml]; nested exception is java.lang.ClassNotFoundException: org.example.bugs.bug.InfoAspect
    at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1266)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:629)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:578)
    at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1335)
    at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:901)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at org.example.bugs.bug.Main.main(Main.java:8)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.ClassNotFoundException: org.example.bugs.bug.InfoAspect
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    at org.springframework.util.ClassUtils.forName(ClassUtils.java:260)
    at org.springframework.beans.factory.support.AbstractBeanDefinition.resolveBeanClass(AbstractBeanDefinition.java:416)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doResolveBeanClass(AbstractBeanFactory.java:1287)
    at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1258)
    ... 15 more



我做错了什么?

【问题讨论】:

    标签: intellij-idea aspectj spring-aop


    【解决方案1】:

    因为您正在尝试使用 Spring AOP 支持的切入点,所以我建议您为此使用 Spring AOP。使用带有完整功能集 AspectJ 的 spring 有点复杂,因为它需要建议编织。此外,&lt;aop:aspectj-autoproxy /&gt; 用于 @AspectJ 风格的 spring AOP,但仍然是 Spring 代理目标,而不是 AspectJ。

    所以我会按照下面的方式转换示例方面:

    @Aspect
    public class InfoAspect {
    
        public InfoAspect() {
        }
    
        @Pointcut("execution(* prospring3.aop.aspectj.Informer.info(..))")
        void infoPointcut() {
    
        }
    
        @AfterReturning("infoPointcut()")
        public void afterReturning(JoinPoint joinPoint) {
            System.out.println("Information confirmed by InfoAspect!");
            System.out.println("joinPoint.getSignature().getName() = " + joinPoint.getSignature().getName());
        }
    
    }
    
    @Configuration
    @EnableAspectJAutoProxy(proxyTargetClass = true) // use the CGLib instead of Java Proxy
    public class AspectJConfig {
    
        @Bean
        public Info info() {
            return new Informer();
        }
    
        /**
         * Aspect must be a config as a bean
         * @return the aspect
         */
        @Bean
        public InfoAspect infoAspect() {
            return new InfoAspect();
        }
    
    }
    
    public class InformerTest {
    
        public static void main(String[] args) {
            ApplicationContext ctx = new AnnotationConfigApplicationContext(AspectJConfig.class);
            final Info bean = ctx.getBean(Info.class);
            bean.info();
        }
    
    }
    

    注意:在 pom.xml 中包含以下依赖项

        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.6.12</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.12</version>
        </dependency>
    

    问候

    【讨论】:

      【解决方案2】:

      你错过了你的 InfoAspect 类..

      您没有在堆栈跟踪中看到org.example.bugs.bug.InfoAspectClassNotFound 吗?也许它不是由 Aspect J 编译的。

      也许你需要另一个教程:

      http://www.tutorialspoint.com/spring/aspectj_based_aop_appoach.htm

      我会确保你有 Spring 3 并使用最新的成语。

      【讨论】:

      • 我在 CLASSPATH 中有所有必需的 JAR,因为 Spring AOP 工作正常。我认为问题出在 [factory-method="aspectOf"] 上。不知道为什么编译好的InfoAspect不存在?
      • 你没有的是你试图创造的方面。您了解 Aspect-J 的工作原理——它在运行时创建字节码。听起来您错过了这一步,因为类加载器找不到您的 InfoAspect。 Aspect-J 编译器/编织器与 Java 编译器是分开的。
      • 这里是 IntelliJ 的 correct 配置。我忘了在模块级别重新定义方面路径。现在一切正常。感谢您的帮助。
      • 我希望您接受并投票以感谢您的回答。这就是它的工作原理。
      • @zajjar,您能否发布解决方案以便其他人可以找到它,链接似乎已损坏。
      猜你喜欢
      • 2015-12-17
      • 1970-01-01
      • 2010-12-09
      • 1970-01-01
      • 2012-07-25
      • 2012-03-28
      • 1970-01-01
      • 1970-01-01
      • 2015-01-20
      相关资源
      最近更新 更多