今天在开发时候,遇到的问题,百思不得其解,情况是这样:
public interface IImportResolverMapper extends SuperMapper{
public void insertDecryptData(@Param("logId")String logId, @Param("physDBName")String physDBName, @Param("synchData")String synchData);
public void insertBlobOrClob(@Param("logId")String logId, @Param("physDBName")String physDBName, @Param("colName")String colName, @Param("condition")String condition, @Param("guid")String guid);
public String getFudsUrl(@Param("typeId")String typeId);
}
上述代码是Mybatis的接口;
我在自己的一个组件中,注入了该类,结果每次在调用时候就报错:BeanNotOfRequiredTypeException
提示需要com.XXX类型bean,但实际是$proxy类型。
心想肯定是哪里注入时类型搞错了,结果查了一个多小时,愣是没发现!网上查了一下,基本问题都是说注入时依赖的不是接口,而是一个具体实现类,但是我这个明显注入时候是mybatis的接口,怎么可能会有这种问题?下面是注入的代码
@Component
public class ImportZipFileResolver implements IImportResolver{
private Logger logger = Logger.getLogger(ImportZipFileResolver.class);
@Resource
private ISynchLogService logService;
@Resource
private IImportResolverMapper importMapper;
后来又查了半天,巧合把这个注入对象名字改了,importMappertt,结果一切都好了!
这才发觉是@Resource注入时,哪里错误产生了问题!于是百度@Resource的作用发现:
1.@Resource应用在字段上,则注入规则是: a.先使用字段名字匹配bean,查找到bean则注入,如果类型不匹配则此时有异常,注入失败。 b.如果字段名字没有匹配到Bean则spring会尝试采用字段类型匹配,如果找打bean则注入,如果字段类型是接口则有可能会匹配到多个类型,则会抛出匹配到多个bean的异常, 注入失败。 2.@Resource应用在setter上(应用到属性),则注入规则是: a.先使用属性名字匹配bean,查找到bean则注入,如果类型不匹配则此时有异常,注入失败。 b.如果属性名字没有匹配到Bean则spring会尝试采用属性参数类型匹配,如果找打bean则注入,如果属性参数类型是接口则有可能会匹配到多个类型,则会抛出匹配到多个bean的异常.注入失败。 注意是属性的参数类型,并不是属性的类型,注意区别 3.小结 a.名称------>b.类型或参数类型(属性时).
标红处,首先会按照对象名称作为beanId去Ioc容器中取,如果没有取到再用类型去匹配!!错就错在我注入时候写得不规范,importMapper在Ioc查找的时候,找到了另外一个Mapper!结果导致那个Mapper和我实际需要的不是一个类型,产生了错误!之前一直认为对象名称无所谓,没想到,还是应该老老实实的按照规范去写!