Spring错误:Bean named 'XXX' must be of type [XXX.XXX]

  在测试Spring使用xml实现aop时出现以下错误:Exception in thread "main" org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'performance' must be of type [Concert.PerformanceImpl], but was actually of type [com.sun.proxy.$Proxy3]

  具体代码如下:

  Audience类:

package Concert;

import org.aspectj.lang.annotation.*;

//@Aspect
public class Audience {

    //@Pointcut("execution(* Concert.Performance.perform(..))")
    public void perform(){}

    //@Before("perform()")
    public void performBefore(){
        System.out.println("表演即将开始,请各位入座");
    }

    //@AfterReturning("perform()")
    public void performce(){
        System.out.println("请尽情开始你的表演。");
    }

    //@After("perform()")
    public void performAfter(){
        System.out.println("表演结束,请离场");
    }

    @AfterThrowing("execution(* Concert.Performance.performFailed())")
    public void Over(){
        System.out.println("表演失败,一切都完了");
    }

}

  Performance接口:

package Concert;

public interface Performance {

    public void perform();
    public void performFailed() throws Exception;

}

 

  PerformanceImpl实现类:

package Concert;

//@Component
public class PerformanceImpl implements Performance {

    public void perform(){
        System.out.println("蹦擦擦,蹦擦擦...");
    }

    public void performFailed() throws Exception {
        throw new Exception();
    }


}

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

    

    <bean id="performance" class="Concert.PerformanceImpl"/>
    <bean id="audience" class="Concert.Audience" />
    <aop:config>
        <aop:aspect ref="audience">
           <aop:pointcut id="perform" expression="execution(* Concert.Performance.perform(..))"/>
            <aop:before method="performBefore" pointcut-ref="perform"/>
             <aop:before method="performBefore" pointcut-ref="perform"/>
            <aop:after method="performAfter" pointcut-ref="perform"/>
            <aop:after-returning method="performce" pointcut-ref="perform"/>
           <aop:after-throwing method="Over" pointcut="execution(* Concert.Performance.perform(..))"/>
        aop:aspect>
    aop:config>

beans>

 

  测试内容:

import Concert.Audience;
import Concert.PerformanceImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {
        /*AnnotationConfigApplicationContext apx = new AnnotationConfigApplicationContext();
        apx.register(Config.class);
        apx.refresh();*/

        ClassPathXmlApplicationContext apx = new ClassPathXmlApplicationContext("classpath:Config/AspectsConfig.xml");


        Audience audience = apx.getBean(Audience.class);
        audience.performAfter();

        PerformanceImpl performance = apx.getBean("performance",PerformanceImpl.class);
        performance.perform();
        try{
            performance.performFailed();
        }catch (Exception e){
           // e.printStackTrace();
        }
        apx.close();
    }

}

 

  原因:Spring 有两种代理动态代理模式,一种是基于接口的JDK动态地理,一种是基于类的CGLibs动态代理,Spring默认是使用JDK动态代理的,所以要么使用JDK动态代理,要么使用CGLibs实现动态代理。

  解决方法:

    

 1、使用基于接口的JDK动态代理:将测试代码中的
   PerformanceImpl performance = apx.getBean("performance",PerformanceImpl.class);
   改为
   Performance performance = apx.getBean("performance", Performance.class);
2、使用基于类的CGLIBS动态代理:在配置文件中添加
  强制使用类代理模式。
 
   
 

转载于:https://www.cnblogs.com/trojane/p/10400966.html

你可能感兴趣的:(Spring错误:Bean named 'XXX' must be of type [XXX.XXX])