package com.smtservlet.mybatis; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.util.Map; import org.apache.ibatis.builder.xml.XMLMapperBuilder; import org.apache.ibatis.builder.xml.XMLMapperEntityResolver; import org.apache.ibatis.executor.ErrorContext; import org.apache.ibatis.parsing.XPathParser; import org.apache.ibatis.session.Configuration; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.mybatis.spring.SqlSessionFactoryBean; import org.springframework.core.io.Resource; import static org.springframework.util.ObjectUtils.isEmpty; public class SMTSqlSessionFactoryBean extends SqlSessionFactoryBean { private Resource[] _mapperLocations; public void setSMTMapperLocations(Resource[] mapperLocations) { this._mapperLocations = mapperLocations; } @Override protected SqlSessionFactory buildSqlSessionFactory() throws Exception { //TestAction app = SMTApp.getBean(TestAction.class); // 如果未设置自定义map列表,则直接调用系统类 if(isEmpty(this._mapperLocations)) return super.buildSqlSessionFactory(); Field f_sqlSessionFactoryBuilder; final SqlSessionFactoryBuilder v_sqlSessionFactoryBuilder; try { // 绑定并替换私有字段sqlSessionFactoryBuilder f_sqlSessionFactoryBuilder = SqlSessionFactoryBean.class.getDeclaredField("sqlSessionFactoryBuilder"); f_sqlSessionFactoryBuilder.setAccessible(true); v_sqlSessionFactoryBuilder = (SqlSessionFactoryBuilder)f_sqlSessionFactoryBuilder.get(this); // 将sqlSessionFactoryBuilder重定向到自定义的类中 f_sqlSessionFactoryBuilder.set(this, new SqlSessionFactoryBuilder() { @Override public SqlSessionFactory build(Configuration configuration) { // 扫描资源库 for (Resource mapperLocation : _mapperLocations) { if (mapperLocation == null) { continue; } try { Constructor c0 = XMLMapperBuilder.class.getDeclaredConstructor(new Class[]{ XPathParser.class, Configuration.class, String.class, Map.class}); c0.setAccessible(true); XMLMapperBuilder xmlMapperBuilder = (XMLMapperBuilder) c0.newInstance( new XPathParser(mapperLocation.getInputStream(), false, configuration.getVariables(), new XMLMapperEntityResolver()), configuration, mapperLocation.toString(), configuration.getSqlFragments()); xmlMapperBuilder.parse(); } catch (Exception e) { throw new RuntimeException( "Failed to parse mapping resource: '" + mapperLocation + "'", e); } finally { ErrorContext.instance().reset(); } } return v_sqlSessionFactoryBuilder.build(configuration); } }); } catch(Exception ex) { throw new IOException(ex); } try { return super.buildSqlSessionFactory(); } finally { try { // 退出时恢复原先的值 if(f_sqlSessionFactoryBuilder != null) f_sqlSessionFactoryBuilder.set(this, v_sqlSessionFactoryBuilder); } catch (Exception e) { } } } }