publicclassGenericTokenParser {privatefinalString openToken;//这个比如#{ 或者${privatefinalString closeToken;//这里基本上就是}privatefinalTokenHandler handler;//根据#{key}或者${key}得到key的值publicGenericTokenParser(String openToken, String closeToken, TokenHandler handler) {this.openToken = openToken;this.closeToken = closeToken;this.handler = handler;}/***这个就是替换的了${key} 然后通过hanlder获取value 拼接进去**/publicString parse(String text) {StringBuilder builder =newStringBuilder();if(text !=null&& text.length() >0) {char[] src = text.toCharArray();intoffset =0;intstart = text.indexOf(openToken, offset);while(start > -1) {if(start >0&& src[start -1] ==‘\\‘) {// the variable is escaped. remove the backslash.builder.append(src, offset, start -1).append(openToken);offset = start + openToken.length();}else{intend = text.indexOf(closeToken, start);if(end == -1) {builder.append(src, offset, src.length - offset);offset = src.length;}else{builder.append(src, offset, start - offset);offset = start + openToken.length();String content =newString(src, offset, end - offset);//拿到#{key}||${key}中的keybuilder.append(handler.handleToken(content));//根据key获取对应的"value"offset = end + closeToken.length();}}start = text.indexOf(openToken, offset);}if(offset < src.length) {builder.append(src, offset, src.length - offset);}}returnbuilder.toString();}}其实最大的区别也就是下面的两个不同的实现类1.${} 的解析实现类判断一下参数的类型,然后就把value给搞定了,没有添加其他的东西,万能的OgnlprivatestaticclassBindingTokenParserimplementsTokenHandler {privateDynamicContext context;publicBindingTokenParser(DynamicContext context) {this.context = context;}publicString handleToken(String content) {Object parameter = context.getBindings().get("_parameter");if(parameter ==null) {context.getBindings().put("value",null);}elseif(SimpleTypeRegistry.isSimpleType(parameter.getClass())) {context.getBindings().put("value", parameter);}Object value = OgnlCache.getValue(content, context.getBindings());return(value ==null?"": String.valueOf(value));// issue #274 return "" instead of "null"}}2.#{} 的解析实现类这里就比较复杂了,判断了javaType,typeHandler,数字精度,通过hanlder,我们就可以处理一些列复杂的数据privatestaticclassParameterMappingTokenHandlerextendsBaseBuilderimplementsTokenHandler {privateList<ParameterMapping> parameterMappings =newArrayList<ParameterMapping>();privateClass<?> parameterType;privateMetaObject metaParameters;publicParameterMappingTokenHandler(Configuration configuration, Class<?> parameterType, Map<String, Object> additionalParameters) {super(configuration);this.parameterType = parameterType;this.metaParameters = configuration.newMetaObject(additionalParameters);}publicList<ParameterMapping> getParameterMappings() {returnparameterMappings;}publicString handleToken(String content) {parameterMappings.add(buildParameterMapping(content));return"?";}//这里就是把#{key}内容进行解析成一个带有一些列属性的类然后再由一些列typehanlder来setValueprivateParameterMapping buildParameterMapping(String content) {Map<String, String> propertiesMap = parseParameterMapping(content);String property = propertiesMap.get("property");Class<?> propertyType;if(metaParameters.hasGetter(property)) {// issue #448 get type from additional paramspropertyType = metaParameters.getGetterType(property);}elseif(typeHandlerRegistry.hasTypeHandler(parameterType)) {propertyType = parameterType;}elseif(JdbcType.CURSOR.name().equals(propertiesMap.get("jdbcType"))) {propertyType = java.sql.ResultSet.class;}elseif(property !=null) {MetaClass metaClass = MetaClass.forClass(parameterType);if(metaClass.hasGetter(property)) {propertyType = metaClass.getGetterType(property);}else{propertyType = Object.class;}}else{propertyType = Object.class;}ParameterMapping.Builder builder =newParameterMapping.Builder(configuration, property, propertyType);Class<?> javaType = propertyType;String typeHandlerAlias =null;for(Map.Entry<String, String> entry : propertiesMap.entrySet()) {String name = entry.getKey();String value = entry.getValue();if("javaType".equals(name)) {javaType = resolveClass(value);builder.javaType(javaType);}elseif("jdbcType".equals(name)) {builder.jdbcType(resolveJdbcType(value));}elseif("mode".equals(name)) {builder.mode(resolveParameterMode(value));}elseif("numericScale".equals(name)) {builder.numericScale(Integer.valueOf(value));}elseif("resultMap".equals(name)) {builder.resultMapId(value);}elseif("typeHandler".equals(name)) {typeHandlerAlias = value;}elseif("jdbcTypeName".equals(name)) {builder.jdbcTypeName(value);}elseif("property".equals(name)) {// Do Nothing}elseif("expression".equals(name)) {thrownewBuilderException("Expression based parameters are not supported yet");}else{thrownewBuilderException("An invalid property ‘"+ name +"‘ was found in mapping #{"+ content +"}. Valid properties are "+ parameterProperties);}}if(typeHandlerAlias !=null) {builder.typeHandler(resolveTypeHandler(javaType, typeHandlerAlias));}returnbuilder.build();}privateMap<String, String> parseParameterMapping(String content) {try{returnnewParameterExpression(content);}catch(BuilderException ex) {throwex;}catch(Exception ex) {thrownewBuilderException("Parsing error was found in mapping #{"+ content +"}. Check syntax #{property|(expression), var1=value1, var2=value2, ...} ", ex);}}}
原文:http://blog.csdn.net/qjueyue/article/details/43974237