com.sun.proxy.$Proxy7 cannot be cast to com.spring.bean.ManImpl

Spring中配置了一个实现类,然后在 getBean 获取该 bean 时,将获取到的对象强制转换为实现类时出现以下错误:
     Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy7 cannot be cast to com.spring.bean.ManImpl

接口类:
 

package com.spring.bean;

public interface HumanInter {
	public void speak();
}

实现类:

package com.spring.bean;

import org.springframework.stereotype.Component;

@Component("man")
public class ManImpl implements HumanInter {

	@Override
	public void speak() {
		System.out.println("I am a man...");

	}

}

配置文件:

<?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"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">

	<context:component-scan base-package="com.spring.bean"></context:component-scan>
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

运行类:

package com.spring.test;

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

import com.spring.bean.ManImpl;

public class Client {

	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		ManImpl man = (ManImpl) ctx.getBean("man");
		man.speak();

	}
}

运行时出现上述错误。

修改办法:

       ① 把 ManImpl man = (ManImpl) ctx.getBean("man"); 的类型改为 HumanInter man = (HumanInter) ctx.getBean("man");

         或者

       ② 看看自己是否配置了该实现类的切面类或者代理类,若有则把配置文件中的  

         <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 去掉,即需要把该类的切面类或者代理类去掉(该方法会导致切

面类或代理类不起作用)

原因:(具体过程如果不理解可以去了解一下 JDK 动态代理的底层原理 https://www.imooc.com/learn/869

        这个错误一般都是代理类或切面类引起的,本程序中也一样,因为配置了一个切面类

        因为当配置了一个切面类或者代理类时,IOC容器当创建这个实现类 bean 实例时,动态代理机制会根据该实现类的接口,

返回一个动态代理类,如上述的例子中执行 ctx.getBean("man") 时会先获取到的如下动态代理类,然后根据该动态代理的实例化

对象调用对应的方法:

        public final class $Proxy0 extends Proxy implements HumanInter{}
        
因为该动态代理类 $Proxy0 实现了 HumanInter 接口,所以由该类的对象是 HumanInter 的一个实现类(但该实现类跟

ManImpl 实现类不等同,不可以进行强制转换,所以上述代码会出错)

 

验证 ctx.getBean("man") 生成的类是否是由动态代理类进行实例化的:
 

package com.spring.test;

import java.lang.reflect.Proxy;

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

import com.spring.bean.HumanInter;
import com.spring.bean.ManImpl;
import com.spring.bean.ManImpl2;

public class Client {

	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		HumanInter man = (HumanInter) ctx.getBean("man");
		System.out.print("man instanceof ManImpl ---> ");
		System.out.println(man instanceof ManImpl);
		
		System.out.print("man instanceof Proxy ---> ");
		System.out.println(man instanceof Proxy);
		man.speak();

	}
}

运行截图:

 由运行截图可知,ctx.getBean("man") 获取到的类对象不是 ManImpl 类的对象,而是 Proxy 类的类对象。 

去掉切面类后的运行截图:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值