$Proxy10 cannot be cast to test1.PoeticJuggler异常处理

来源:互联网 发布:mysql session 编辑:程序博客网 时间:2024/06/07 13:46
  • 今天在测试Spring切面编程的时候,偶然遇到了一个问题,问题描述见标题,代码如下:
接口类Performerpublic interface Performer {    public void perform();//表演者}
Performer的实现类Jugglerpublic class Juggler implements Performer{    private int beanBags=3; //抛豆子,默认一次抛3袋    public Juggler(){}    public Juggler(int beanBags){        this.beanBags=beanBags;    }    public void perform() {        System.out.println("JUGGLER    "+beanBags+"     BEANBAGS");    }
Juggler的继承类PoticJugglepublic class PoeticJuggler extends Juggler{//这里能配合干点别的什么,比如这个人能表演杂技和朗诵诗歌    public PoeticJuggler(int beanBags){        super(beanBags);        //其他    }    @Override    public void perform() {        super.perform();        //其他    }}
切面类Audiencepublic class Audience {//表演前通知    public void takeSeats(){        System.out.println("The audience is taking thier seats!");    }    //表演前通知    public void turnOffCellPhone(){        System.out.println("The audience is turning off thier cellphones");    }    //表演后通知    public void applaud(){        System.out.println("CLAP  CLAP  CLAP  CLAP");    }    //异常通知    public void demandRefund(){        System.out.println("Boo! We want out money back!");    }}
XML的配置如下:    <bean id="Duke" class="test1.Juggler">                <constructor-arg value="15"/>            <bean id="poeticDuck" class="test1.PoeticJuggler">                <constructor-arg value="15"/>            </bean>            <bean id="audience" class="test1.Audience"/>             <aop:config>                <aop:aspect ref="audience">                <aop:pointcut expression="execution(* *.perform(..))" id="performence"/>                <aop:before method="takeSeats" pointcut-ref="performence"/>                <aop:before method="turnOffCellPhone" pointcut-ref="performence"/>                <aop:before method="applaud" pointcut-ref="performence"/>                <aop:before method="demandRefund" pointcut-ref="performence"/>            </aop:aspect>            </aop:config> 
测试代码:    public static void main(String[] args) {        ApplicationContext context=new ClassPathXmlApplicationContext("ApplicationContext.xml");        PoeticJuggler duke=(PoeticJuggler) context.getBean("poeticDuck");        duke.perform();    }
结果:Exception in thread "main" java.lang.ClassCastException: $Proxy10 cannot be cast to test1.PoeticJuggler    at test1.Test.main(Test.java:12)提示不能够铸造PoeticJuggler类(类型转换错误)
  • 为什么会出现这个错误呢?
    首先,在声明切面编程的时候,指定的切入点是perform方法,而纵观整个程序代码,perform方法是由Performer接口产生的,由Juggle实现,由PoeticJuggler重写,在测试的时候,指定的类型为PoeticJuggler,由这个类来执行perform方法,这就是出现错误的根源,如果将类型改为Performer类型,则程序能正常运行,具体错误原因本人知识有限尚未分析出来,希望有知道的朋友可以留言解释一下,万分感谢。

  • 查看了一下其他人的博客有说到这点

spring的文档中这么写的:Spring AOP部分使用JDK动态代理或者CGLIB来为目标对象创建代理,如果被代理的目标对象实现了至少一个接口,则会使用JDK动态代理。所有该目标类型实现的接口都将被代理。若该目标对象没有实现任何接口,则创建一个CGLIB代理。使用beanNameAutoProxyCreator来进行事务代理的话,他的proxyTargetClass这个属性设置为false(默认是false),即使用JDK动态代理,如果你的service类没有实现接口的话,就会报类型转换错误。解决办法有:1、给service类添加一个接口iService,让service类实现它,则创建代理类时使用JDK动态代理就不会出现问题2、设置beanNameAutoProxyCreator的proxyTargetClass属性为true,意思是强制使用CGLIB代理,前提是你已经将CGLIB包加入到项目中来自:http://mopishv0.blog.163.com/blog/static/54455932200911118572079/
阅读全文
0 0