首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

spring的auto-proxy自动署理(融合机制实现)

2012-12-26 
spring的auto-proxy自动代理(融合机制实现)背景最近在实施并行加载,遇到一个问题: 重复代理,或者说是两次c

spring的auto-proxy自动代理(融合机制实现)
背景

最近在实施并行加载,遇到一个问题: 重复代理,或者说是两次cglib代理。

主要是并行加载技术本身是采用了cglib+拦截的技术进行控制,所以势必会要求进行一次代理配置那

1. 如果需要代理的原始对象已经是一个cglib代理后的对象,比如性能监控,日志记录等等。

2. 其他同事在做的自动路由,按需加载都会要求进行一次cglib代理

?

如何平衡多次代理的问题,就冒出来了。

思路

接近于spring的autoProxyCretor的一套机制,利用了BeanPostProcessor,就是在bean的生命周期上做点文章。

?

spring默认提供的几种auto-proxy:?

?

BeanNameAutoProxyCreator ? : ?可以配置需要被进行auto-proxy的bean names列表,它控制的是需要代理的bean列表InfrastructureAdvisorAutoProxyCreator ?DefaultAdvisorAutoProxyCreator?: ?将对应匹配的advisor,自动添加到spring的bean。它控制的是advisor的匹配,所有的bean都会被自动代理
再思考一下我自己的需求:1. ?允许和BeanNameAutoProxyCreator指定对应的bean names和inteceptorNames,而不是自动代理所有的bean。

?

2. ?如果原始对象是proxyFactoryBean,配置的并行加载拦截器是基于同一个proxyFactoryBean3. ?多次的融合机制,是可以进行合并处理。 因为不同的框架会自定义配置一份代理拦截,需要将两份拦截器进行合并处理。
针对该需求的解决方案:1. 继续引用auto-proxy的那套机制,基于BeanPostProcessor在bean的生命周期初始化的最后一环节进行切入。
切入代码:

代码实现代码:https://code.google.com/p/asyncload/source/browse/trunk/src/main/java/com/agapple/asyncload/impl/spring/CompositeAutoProxyCreator.java?测试代码:https://code.google.com/p/asyncload/source/browse/trunk/src/test/java/com/agapple/asyncload/spring/AsyncLoadSpringCompsiteTest.java

配置文件:https://code.google.com/p/asyncload/source/browse/trunk/src/test/resources/asyncload/applicationContext.xml,查找对应的Compsite

?

最后

在查找具体的解决方案是一个比较曲折的过程,基本上把ProxyFactoryBean机制,auto-proxy机制代码实现都看了一遍。

过程1 : 原先是寄希望于spring可以提供类似的一个global advisor的概念,每个ProxyFatoryBean除了自己配置的inteceptorNames的拦截器之外,还回从一些global的定义中获取一些大家公用的advisor。找了一圈发现没有,曾经的GlobalAdvisorAdapterRegistry给了我一些希望,最后发现是一个绝望的内容。 

?

过程2:在看AutoProxyCreator那套机制时,其实它预留了一些扩展点,主要是根据bean name获取对应的auto-proxy信息。bean name到具体的bean的处理,因为是在BeanPostProcessor,处于getBean()生命周期的最后一步,如果此时进行this.beanFactory.getBean()就是一个死循环,此路不通,所以原先的auto-proxy相关的扩展点基本走不同。

?

过程3: 在2走不通后,一直在琢磨是否可以通过直接处理生成后的object,获取原始object对应的ProxyFactoryBean.getAdvsisor()方法。后来看了半天代码,发现也是条思路,因为proxyFactoryBean生成的proxy对象完全和ProxyFactoryBean无关,也就不会有getAdvisor()方法,因为生成的cglib代理或者jdk代理,cglib代理到还有对advised的引用持有,有办法通过反射获取。而jdk那个压根没则,所以有是一条思路。

?

过程4: 2,3都走不通了,今天在debug另一个问题时,发现BeanPostProcessor的相应callback方法中传递的bean object居然是原生的ProxyFactoryBean,也就是说未进行getObject()调用之前的原始对象。大喜,总于找到突破口,最后就是自己实现了一套auto-proxy机制,因为原先的扩展点不支持传递bean object对象。

?

最后只能说自己对spring的一些机制还不够了解,需要持续加强。发现去扩展spring的一些点,是学习spring最快的一种方式,找扩展点的过程是对spring的一个总体把握的过程


悟了3天的问题,总于有了解决方案,仅以此文几年一下我那3天死去的脑细胞!!

热点排行