MethodOverrides方法的覆盖源码分析
如下xml配置:

<bean id="getBeanTest" class="springSourseAnalyes.GetBeanTest" lazy-init="true">
<lookup-method name="getBean" bean="stu" />
</bean>
<bean id="stu" class="springSourseAnalyes.Student" lazy-init="true"/>
<bean id="teacher" class="springSourseAnalyes.Teacher" />
<bean id="testChangeMethod" class="springSourseAnalyes.TestChangeMethod">
<replaced-method name="chanageMe" replacer="replacer" />
</bean>
<bean id="replacer" class="springSourseAnalyes.TestMethodReplcer"/>
抽象类GetBeanTest代码:
package springSourseAnalyes;
public abstract class GetBeanTest {
public void showMe(){
getBean().showMe();
}
abstract User getBean();
}
User类和Teacher类代码:
package springSourseAnalyes;
public class User {
void showMe(){
System.out.println("i am user");
}
}
package springSourseAnalyes;
public class Teacher extends User{
@Override
void showMe() {
// TODO Auto-generated method stub
System.out.println("i am Teacher");
}
}
其实MethodOverrides的作用就是在spring配置中存在lookup-mehtod和rreplace-method的,而这两个配置在加载xml的时候就会统一存放在BeanDefinition中的methodOverrides属性里。
查看源码AbstractAutowireCapableBeanFactory的创建bean的方法create:

这时候GetBeanTest类已经是class类,开始调用准备方法的覆盖,继续进入方法prepareMethosOverrides()。
查看源码AbstractBeanDefinition

遍历MethodOverrides,对于一个方法的匹配来j讲,如果一个l类中存在若干个重载方法,那么,在函数调用以及增强的时候还需要根据参数类型进行匹配,来最终确认当前调用的到底是哪个函数,但是,spring将一部分匹配工作在这里完成了,如果当前类中的方法只有一个,那么就设置重载该方法没有被重载,这样在后续调用的时候便可以直接使用找到的方法,而不需要j进行方法的参数匹配了,而且还可以提前对方法存在性进行验证。
进入帮助类ClassUtils

使用递归方式来遍历当前类的方法,是否与methodName匹配,如果匹配则count计数器自增,然后对当前类的接口进行遍历匹配操作,然后在对当前类的超类进行遍历匹配。返回计数器。
递归先后遍历:1、当前类方法遍历。2、当前类接口的方法遍历。3、当前类超类的方法遍历。
最终返回的是一个对当前类的代理类。通过CGLIB生成不同的代理类。

其中owner 是BeanFactory 接口、beanDefinition为RootBeanDefinition类
当调用方法时,就会被拦截调用intercept方法,获取到该方法的替换者bean类,然后在通过owner.getBean来获取bean类,然后真正调用被替换的方法。

本文详细解析了Spring框架中MethodOverrides的功能与实现原理,重点介绍了lookup-method和replace-method配置的作用,以及它们如何在BeanDefinition中存储和应用。通过源码分析,展示了在bean创建过程中,如何通过CGLIB生成代理类来实现方法的覆盖与替换。
578

被折叠的 条评论
为什么被折叠?



