为什么spring使用自动注入实现类的时候会报错?

TaskDao是接口,TaskDaoImpl是TaskDao的实现类,下面语句正常:

@Autowired
protected TaskDao taskDao ;

如果自动注入实现类就会报错:

@Autowired
protected  TaskDaoImpl taskDaoImpl;

报错如下:

Bean named 'TaskDaoImpl' must be of type [com.changetech.dao.impl.TaskDaoImpl], but was actually of type [$Proxy98]

但是如果让TaskDaoImpl不去实现接口,直接是普通的类,那么也可以正常运行。

大概能猜到是因为前者使用jdk动态反射,后者能成功是cglib反射,但是还是不太清楚具体机制。

阅读 7.7k
4 个回答

只需要自动注入接口,spring是通过自动代理帮接口去找实现的。

你这个只需要注入持久层接口就好了,apring会自动帮你生成代理实现类,提供给你调用,不需要注入实现类,这样代理类注入就会出问题,从而报错

新手上路,请多包涵

可以了解一下IOC容器启动过程的源码,跟踪一下AbstractAutowireCapableBeanFactory中applyPropertyValues方法,就熟悉注入的过程了

两种代理方式差别:

  1. JDK 动态代理(即 java.lang.reflect.Proxy 类)提供的 API 只支持接口代理(即 Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 第二个参数是接口列表)
  2. cglib 采用动态插入字节码的方式实现的,因此可以在任何地方插入字节码,所以支持类的代理。

关于 Proxy 类详见官方文档:https://docs.oracle.com/javas...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题