没有实现接口的一个问题
没有实现接口的一个问题
最近因为偷懒,发现了spring里面的一些隐藏机制.拿出来大家一起开心下.
项目需要,这边需要写一个全局拦截器,在spring的体系下,弄个拦截器,那简直就是个菜.
- 我意气风发
- 我快刀斩乱麻
一个简单的小程序,很快就搞好了,弄个单元测试看看,报错……,而且是个很神奇的No qualifying bean of type
我左看右看,明明都注册了呀,为啥还是找不到type呢…. 
我随风凌乱,整理一把思路,把一些花里胡哨的技巧统统删除,全部使用spring最古老的bean的xml载入,还是个错.
嘿..牛脾气一下子就上来了…..凭啥,治不了女人还治不了你了,小样….
看了3个小时,还是没看出问题来,这么改,都是那个烦人的错…..
抽空写了个aop配置式的代理,突然发现,没问题了….这个就整郁闷了…….
把spring的载入日志都打开,仔细翻看载入的过程,最终发现如下问题


代码中的TestService,在原有@Transactional的作用下,会被一开始就弄成代理,而且是CGLib代理,而在自定义拦截的时候,本来想show一下隐藏型的代理方式,使用了org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator 这个生成代理的方式居然是JDK代理,把cglib的代理对象又代理了一遍.
提示
为什么是org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator,这个就是使用代码的方式,实现AOP的创建类.
注意
嗯??不对,TestService没有接口,为什么会使用JDK代理???哪来的接口???
又是一顿源码,终于被我逮到了

spring在使用cglib代理的时候,会把advise的接口传给被代理的类,被代理的类就有了接口,而最终在testcase中引入TestService,因为没有接口,所以直接向spring请求的类,最终导致spring中没有这个类型.
注意
还是不对,为什么已经被CGLib代理,又再次被JDK代理呢??
这边应该是和spring的加载顺序有关了,因为spring在判断一个已经被代理类的时候,就是用advisor判断的,就是用的BeanFactory.getBean(advisor)的接口判断的.
估计是spring也没有想到,我的代码会不实现接口,直接使用类来进行玩吧.
但其实这种情况,在我们平常写代码的时候,经常出现.
总结
治不了女人,一定要把spring治好,女人是家里的事,spring是生存的事,孰重孰轻,一清二楚.
这么一个简单的问题,追踪到最后就能最终到spring的加载顺序了.所谓条条大路通罗马,万物归宗以后,世界上总有那么多问题会归类汇总到某些关键点上.在java的世界里,spring就是第二个JDK,需要用我们所有的力量来刨根问底.
