這裏也只使用一個例子來分析java
1 方法bindMapperForNamespaceapp
private void bindMapperForNamespace() { // cn.vansky.schedule.time.menu.dao.MenuMapper String namespace = builderAssistant.getCurrentNamespace(); if (namespace != null) { Class<?> boundType = null; try { // 根據命名空間來查詢相應的接口 // interface cn.vansky.schedule.time.menu.dao.MenuMapper boundType = Resources.classForName(namespace); } catch (ClassNotFoundException e) { //ignore, bound type is not required } if (boundType != null) { if (!configuration.hasMapper(boundType)) { // Spring may not know the real resource name so we set a flag // to prevent loading again this resource from the mapper interface // look at MapperAnnotationBuilder#loadXmlResource // 加載過的資源添加到Configuration(全局配置類)裏 // 屬性爲Set<String> loadedResources = new HashSet<String>() configuration.addLoadedResource("namespace:" + namespace); // 加載的Mapper添加到Configuration(全局配置類)裏 // 屬性爲MapperRegistry mapperRegistry = new MapperRegistry(this) configuration.addMapper(boundType); } } } }
上面把加載過的資源文件與加載過的SQLMapper文件放入到Configuration(全局配置類)中。ui
MyBatis也支持註解方式,那麼註釋是怎麼注入的呢?這個代碼就在addMapper方法裏面,就來看看相應的代碼。this
public <T> void addMapper(Class<T> type) { if (type.isInterface()) { if (hasMapper(type)) { throw new BindingException("Type " + type + " is already known to the MapperRegistry."); } boolean loadCompleted = false; try { knownMappers.put(type, new MapperProxyFactory<T>(type)); // It's important that the type is added before the parser is run // otherwise the binding may automatically be attempted by the // mapper parser. If the type is already known, it won't try. MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type); // 註解的解析 parser.parse(); loadCompleted = true; } finally { if (!loadCompleted) { knownMappers.remove(type); } } } }
這裏不在對註解方式進行分析,有興趣的童鞋,能夠自行分析一下。spa
上圖就是Configuration(全局配置類)中添加Mapper的位置及相應的屬性。code