Mybatis-Spring(2)MapperFactoryBean
接上一节,BeanDefiniton设置
//1、BeanDefiniton将自己的构造器设置为自己的className definition.getConstructorArgumentValues().addGenericArgumentValue(definition.getBeanClassName()); //2、BeanDefiniton将自己的BeanClass设置为:MapperFactoryBean.class definition.setBeanClass(this.mapperFactoryBean.getClass()); //3、BeanDefiniton设置属性sqlSessionFactory definition.getPropertyValues().add("sqlSessionFactory", new RuntimeBeanReference(this.sqlSessionFactoryBeanName));
实例化Bean
1、调用构造方法实例化MapperFactoryBean
public MapperFactoryBean(Class<T> mapperInterface) { this.mapperInterface = mapperInterface; }
2、设置属性,MapperFactoryBean的父类SqlSessionDaoSupport.setSqlSessionFactory方法
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { if (!this.externalSqlSession) { this.sqlSession = new SqlSessionTemplate(sqlSessionFactory); } }
2、调用afterPropertiesSet
@Override public final void afterPropertiesSet() throws IllegalArgumentException, BeanInitializationException { // Let abstract subclasses check their configuration. checkDaoConfig(); // Let concrete implementations initialize themselves. try { initDao(); } catch (Exception ex) { throw new BeanInitializationException("Initialization of DAO failed", ex); } }
调用 checkDaoConfig,将mapperInterface放入configuration中,
configuration.addMapper(this.mapperInterface) 会解析 mapperInterface (mapperInterface)对应的XML和注解。
protected void checkDaoConfig() { super.checkDaoConfig(); notNull(this.mapperInterface, "Property 'mapperInterface' is required"); Configuration configuration = getSqlSession().getConfiguration(); if (this.addToConfig && !configuration.hasMapper(this.mapperInterface)) { try { configuration.addMapper(this.mapperInterface); } catch (Exception e) { logger.error("Error while adding the mapper '" + this.mapperInterface + "' to configuration.", e); throw new IllegalArgumentException(e); } finally { ErrorContext.instance().reset(); } } }
因为是FactoryBean,用到的是FactoryBean.getObject()返回的数据。
public T getObject() throws Exception { return getSqlSession().getMapper(this.mapperInterface); }
最终返回的是一个代理对象:mapperProxyFactory.newInstance(sqlSession);
public <T> T getMapper(Class<T> type, SqlSession sqlSession) { MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type); if (mapperProxyFactory == null) { throw new BindingException("Type " + type + " is not known to the MapperRegistry."); } else { try { return mapperProxyFactory.newInstance(sqlSession); } catch (Exception var5) { throw new BindingException("Error getting mapper instance. Cause: " + var5, var5); } } }
总结:
对于一个MapperInterface,在Spring中会存在一个BeanDifition,两个实例:MapperFactory<MapperInterface.class> 和 ProxyBean。