问题描述
Service类中自动注入一个mapper,运行后发现注入失败无法使用。
@Component
public class KeyService {
@Resource
XXXKeyMapper xXXKeyMapper;
...
}
@Mapper
public interface XXXKeyMapper extends BaseMapper<Object>{
List<String> queryByAk(String ak); // 具体方法用同名xml中的sql语句实现
}
排查:mapper.java和mapper.xml的目录
mapper.java和mapper.xml需要有相同的path from source root,例如:
mapper.java:com/aliyun/{department}/{project}/{module}/mapper/XXXKeyMapper.java
mapper.xml:com/aliyun/{department}/{project}/{module}/mapper/XXXKeyMapper.xml
排查:mapper.xml的namespace
namespace出错时会在编译时报错Error while adding the mapper xxx to configuration.
namespace应该指向mapper.java的reference path
排查:application中的@MapperScan
如果运行时没有指定扫描该mapper的路径则也会出现找不到bean的情况,需要在application的注解中加上
@MapperScan(value = {"com.aliyun.{department}.{project}.{module}.mapper*"})
排查:待注入Mapper类的新建方式
使用反射class.newInstance()获取实例时,实例中的@Autowired无法自动注入,因为反射与Spring的IOC容器无关,所以应该改为KeyService service = applicationContext.getBean(KeyService.class)
好了虽然看起来是个弱智的bug但是因为新建实例的逻辑在二方库里而mapper在应用里,所以排查起来只想到了mapper这边,查了好久才想到新建实例这边也可能有问题,只能说debug时间越长,bug越让人无语。。。。。