spring aop 动态代理批量调用方法实例
今天项目经理发下任务,需要测试 20 个接口,看看推送和接收数据是否正常。因为对接传输的数据是 xml 格式的字符串,所以我拿现成的数据,先生成推送过去的数据并存储到文本,以便验证数据是否正确,这时候要批量调用这些同名方法,我觉得这里可以发展成有潜力的代码。
推送比较好做数据,队友们都写好代码,但是有个问题,方法要的值都大致相同,封装的方式不一致,多人开发,有的封装对象里面,有的直接使用 Map.get(),唉,一千个人一千个哈姆雷特嘛,只好利用反射和动态代理节省自己的代码量,而且这种方式练练手,看上去屌屌的,我喜欢。
对接是使用基于 webService 的 cxf 跟对方的 axis2 做 SOA 对接。 这两个框架兼容性上有问题,幸好同事已经解决了。 类对应的 url 已经封装好了,写在配置文件properties 中,以传输实体类bean 为键,对方的url 为键值对。
思路
- 要根据系统现有数据输出到文件,方便一个一个检查核对文档。
 - 它们都是实现同一接口。(Spring 实现一个及以上接口就会使用JDK动态代理,否则使用cglib)
 - 那可以判断是否实现同一个接口来拿 Service。
 - 要做这样的判断,要使用反射和动态代理调用方法。
 - 可以使用类名获取 Spring管理的类,那就可以字符串数组或集合来搞。
 - 取得代理类,强转为业务接口类再调用方法。
 - 调用方法需要形参,那就要的时候再造,而且数据大致一样,可以使用同一个成员变量。
 - 先去系统看看哪个批次数据比较充足的。
 - 声明这些公用数据。
 - 开始动手写。
 
接口说明:
- 接口都继承一个顶层接口 IBaseTradingCenter( TradingCenter = 交易中心)
 - 接口分为推送 IBaseTradingCenterClient,接收为 IBaseTradingCenterServer
 - 只有一个接口方法 synch
 - 接受两个参数 Object 和 Map<String, Object>
 - Object 是给传输Bean赋值的实体,Map 作为其他值的补充
 - 没有返回值
 - 抛出异常
 - 实现该接口的类全都处于Spring 管理
 
做法是这样的:
- 将这 20 个实现接口的的类的类名(例如: TenderReturnService.java),直接使用字符串数组存储,包含推送和接收(未区分,后面区分),使用字符串截取和首字符大小写处理一下。
 - 遍历数组,使用 Spring 的 WebApplicationContextUtils 获取传入字符串,获取 20 个 Service 的代理类 $Proxy0。
 - 使用 instanceof 判断代理类是否实现 IBaseTradingCenterClient(推送)接口,如果是,则用 IBaseTradingCenterClient 强制转型并存储到 List<IBaseTradingCenterClient> 中。
 - 大概获取到10个左右的推送类。(存储到List可以省略,但为代码可阅读还是不能省)
 - 遍历 List<IBaseTradingCenterClient> ,实际里面都是代理对象。
 - 需要判断代理对象的原始对象是否等同我们的业务类。
 - 查阅了一下资料,看了一下 AopUtils 源码,里面有几种方法可以使用,spring aop 有封装自己的代理模式。
 - AopUtils.isProxy() 判断是否是代理类、AopUtils.getTargetClass() 获取代理类目标对象(原始类)的 class 这两个方法我用得上。
 - AopUtils.getTargetClass() 获取原始类的 class,再跟业务类的 class 直接用 “==” 比较,为 true 原始类为该业务类。
 - 构造形参 Object 和 Map,传入代理类方法 $Proxy.synch(Object, Map)。
 - 在 Bean2XmlUtils 工具类中使用 FileUtils.writeString(str, data)写出文件。
 - 检查文件生成情况。
 - 完成。
 
改进
这里还有个问题需要解决:
- 形参的问题,形参都是不一样的对象,但是使用的字段基本一样。
 - 这里我想到使用 BeanUtils 。但是这个工具类只是做对象与对象的拷贝。
 - 我可以这样想,反射得到对象的成员变量名称,用名称去一个 Map 中获取数值,如果能获取,则将 Map 中的值赋值给成员变量。那么就可以解决不同的形参对象的问题。
 - 声明一个 BeanUtils.setBeanForMap(Obj, Map)
 
                    
                
                
            
        
浙公网安备 33010602011771号