`
michael.softtech
  • 浏览: 208525 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

spring 中用到cglib的几个地方

阅读更多

 

今天闲着没事翻Spring源代码的时候,又看到了InstantiationStrategy这个接口。

这个接口的实现类是用来实例化bean的。看了一下,发现在spring里面有有这个接口的实现层次是这样的:

          <<Interface>>InstantiationStrategy

                        |

                        |

           SimpleInstantiationStrategy

                        |

                        |

          CglibSubclassingInstantiationStrategy

 

  对于CglibSubclassingInstantiationStrategy,有这么一句注释:

  Default object instantiation strategy for use in BeanFactories.

 

  这个与SimpleInstantiationStrategy最大的区别是支持Method Injection. 其中Method Injection的实现

  需要依靠Cglib.具体代码就不贴了。总之就是通过Cglib重新生成一个原来的类的子类,在新的类中对需要注入的方法

  进行了overwrite.

 

  到了这里,自然而然的也就想到了Cglib在Spring中另外一处重要的应用,那就是aop.

 Spring 的aop的代理方式有两种可以选择,一是JdkDynamicProxy,另一个就是CglibProxy.

 在aop中bean的代理生成最终发生在DefaultAopProxyFactory这个类中,代码如下:

 

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
			Class targetClass = config.getTargetClass();
			if (targetClass == null) {
				throw new AopConfigException("TargetSource cannot determine target class: " +
						"Either an interface or a target is required for proxy creation.");
			}
			if (targetClass.isInterface()) {
				return new JdkDynamicAopProxy(config);
			}
			if (!cglibAvailable) {
				throw new AopConfigException(
						"Cannot proxy target class because CGLIB2 is not available. " +
						"Add CGLIB to the class path or specify proxy interfaces.");
			}
			return CglibProxyFactory.createCglibProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}
 

   可以看到,当bean中设置proxyTargetClass属性为true,或者bean本什么没有implements任何接口(以及其他一些 比较特殊情况optimize,啊哈我不知道这个optimise是干什么用的),那么将采用cglib的代理方式。否则采用JdkDynamicProxy代理方式。值得注意的是当bean只是一个接口的时候,将采用JdkDynamicProxy方式。

 

既然说到这里了,就顺便把两种代理方式也比较一下吧。从概念上来说,java 动态代理是通过接口代理的方式,产生一个

和被代理类有相同接口的类。原理就是通过InvocationHandler接口的方式控制对原来的class的method的访问,

在访问前后加入我们自定义的行为。 而cglib则是通过操作字节码的方式生成一个原来的class的subclass.原理也是把我们自定义的MethodInterceptor加入到新生成的类的里面去。

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics