getbean时,如果没有用代理,如果bean没有配置lookup-method和replace-method则采用JDK反射否则使用CGLIB。
在Spring源代码中有这样一段代码
public Object instantiate(
RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (beanDefinition.getMethodOverrides().isEmpty()) {
return BeanUtils.instantiateClass(beanDefinition.getBeanClass());
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(beanDefinition, beanName, owner);
}
}
那么究竟什么时候使用JDK来创建Bean,什么时候使用CGLIB来创建Bean呢?
我注意到源代码中有以下的表述
// Don't override the class with CGLIB if no overrides.
if (beanDefinition.getMethodOverrides().isEmpty()) {
……
}
那么是什么条件才会触发这个MethodOverrides呢?
其实是Spring配置文件中的lookup-method和replace-method,
这其实是两个方法级别的注入,和一般的属性(Property)注入是不一样的,
它们注入的是方法(Method)。
两者的差别是这样的
- 如果需要替换的方法没有返回值,那么只能使用replace-method来替换,而不能用lookup-method来替换。
- replace-method必须实现MethodReplacer接口的Bean才能替换,而lookup-method则由BeanFactory自动为我们处理了。