1.错误原因
SpringAOP中的AspectJ动态代理出现ClassCastException,原因是不能强制转换为TeamService类。
java.lang.ClassCastException: class com.sun.proxy.$Proxy14 cannot be cast to class com.pdh.service.Impl.TeamService
(com.sun.proxy.$Proxy14 and com.pdh.service.Impl.TeamService are in unnamed module of loader 'app')
获取实例对象代码,TeamService实现了IService接口
TeamService iService = (TeamService) applicationContext.getBean("teamService");
2.分析:
1.AspectJ的动态代理分为JDK动态代理和CGLIB动态代理,在AspcetJ代理的时候使用哪一种代理方式取决于被代理类是否实现接口,实现了接口就使用JDK动态代理,没有实现接口就使用CGLIB动态代理,而在我遇到的这个异常当中,我使用TeamService实现了IService接口,且使用xml实现的SpringAOP,Spring应该是使用JDK动态代理来实现AOP。
2.JDK动态代理是代理的接口,因此强制转换应该转换为接口,而不是实现类,若强制转换实现类就会抛出ClassCastException,好比ArrayList与LinkedList实现统一接口List,两者也不能相互转换,但都可以向上转型。
3.解决办法:
使用接口进行强转
IService iService = (IService) applicationContext.getBean("teamService");
这样处理以后就不再报ClassCastException。
4.求解
我再测试的时候我有一个疑惑,我使用注解方式实现springAOP时,再获取目标对象的时候,我直接使用接口的实现类进行强转,没有发生ClassCastException异常,能正常运行:
TeamService iService = (TeamService) applicationContext.getBean("teamService");
那么这里与使用xml方式实现springaop是有什么区别呢,下面这种使用注解实现aop的方式是使用了cglib动态代理吗?如果是的话那么我实现的接口到底怎么样才能被spring正确识别,如果不是那么我使用的实现类也能进行JDK动态代理?搞不懂…