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">

    <!--<aop:aspectj-autoproxy proxy-target-class="true"/>-->

    <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動態代理:在配置文件中添加
  <aop:aspectj-autoproxy proxy-target-class="true"/>強制使用類代理模式。
 
        
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM