23、Mapper解析之基于注解的总体过程

本文详细解析了基于注解的Mapper接口解析过程,从mapperElement方法开始,探讨了MapperRegistry、MapperAnnotationBuilder等关键步骤。内容涵盖了包配置、MapperRegistry的字段和方法、MapperAnnotationBuilder的字段和方法,以及解析缓存、Statement和ResultMap的过程。总结了在全局配置文件中使用package配置时,如何根据包名找到对应的mapper路径,并完成接口解析。
摘要由CSDN通过智能技术生成

mapper文件入口

加载mapper配置文件的入口在XMLConfigBuilder类中的mapperElement方法

mapperElement方法

  private void mapperElement(XNode parent) throws Exception {
        if (parent != null) {
            for (XNode child : parent.getChildren()) {
                if ("package".equals(child.getName())) {
                    String mapperPackage = child.getStringAttribute("name");
                    configuration.addMappers(mapperPackage);
                } else {
                    String resource = child.getStringAttribute("resource");
                    String url = child.getStringAttribute("url");
                    String mapperClass = child.getStringAttribute("class");
                    if (resource != null && url == null && mapperClass == null) {
                        ErrorContext.instance().resource(resource);
                        InputStream inputStream = Resources.getResourceAsStream(resource);
                        XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
                        mapperParser.parse();
                    } else if (resource == null && url != null && mapperClass == null) {
                        ErrorContext.instance().resource(url);
                        InputStream inputStream = Resources.getUrlAsStream(url);
                        XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments());
                        mapperParser.parse();
                    } else if (resource == null && url == null && mapperClass != null) {
                        Class<?> mapperInterface = Resources.classForName(mapperClass);
                        configuration.addMapper(mapperInterface);
                    } else {
                        throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");
                    }
                }
            }
        }
    }

这个方法首先会加载<mappers>标签下的package节点,如果package节点为空,则解析
resource url class这三个节点从上面的if判断可以看出,如果三个不满足只有其中一个的话就会发生异常,异常的信息为
A mapper element may only specify a url, resource or class, but not more than one.

package

我们首先来分析package节点,package配置的mapper接口所在的包,涉及的重要方法有以下几个

MapperRegistry

mapper文件的注册

字段

  private final Configuration config;
  private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<Class<?>, MapperProxyFactory<?>>();

knownMappers存放注册的mapper文件,key为mapper接口的类型,value为mapper接口的动态代理对象,动态代理对象如何生成,随后分析

方法

  /**根据包名,解析出包下的所有类
   * @since 3.2.2
   */
  public void addMappers(String packageName, Class<?> superType) {
    ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<Class<?>>();
    resolverUtil.find(new ResolverUtil.IsA(superType), packageName);
    Set<Class<? extends Class<?>>> mapperSet = resolverUtil.getClasses();
    for (Class<?> mapperClass : mapperSet) {
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值