Author: HuiFer
源码阅读仓库: SourceHot-spring
org.springframework.beans.factory.support.MethodOverride
org.springframework.beans.factory.support.LookupOverride
org.springframework.beans.factory.support.ReplaceOverride
org.springframework.beans.factory.support.MethodOverrides
- MethodOverride 方法重载类
在MethodOverride
定义了下面三个属性
- 方法名称
- 是否重载
- 源
publicabstractclassMethodOverrideimplementsBeanMetadataElement { /** * 方法名称 */privatefinalStringmethodName; /** * 是否重载 */privatebooleanoverloaded = true; /** * 源 */@NullableprivateObjectsource; }
- 定义了一个抽象方法, 交由子类实现
publicabstractbooleanmatches(Methodmethod);
类图
在 Spring 中有两种可以重写的机制(XML)
lookup-method
标签<lookup-methodname=""bean=""/>
replaced-method
标签<replaced-methodname=""replacer=""/>
相对应的两个类如类图所示
org.springframework.beans.factory.support.LookupOverride
- lookup-method 标签对应的实体对象
属性列表
- beanName
- method
@NullableprivatefinalStringbeanName; @NullableprivateMethodmethod;
比较方法
- method 是否直接相等
- method 名称是否相同
- 是否需要重载
- 是不是 ABSTRACT 方法
- 参数列表长度是否等于 0
@Overridepublicbooleanmatches(Methodmethod) { if (this.method != null) { // 通过 equals 判断returnmethod.equals(this.method); } else { // 1. method 名称是否相同// 2. 是否需要重载// 3. 是不是 ABSTRACT 方法// 4. 参数列表长度是否等于0return (method.getName().equals(getMethodName()) && (!isOverloaded() || Modifier.isAbstract(method.getModifiers()) || method.getParameterCount() == 0)); } }
org.springframework.beans.factory.support.ReplaceOverride
/** * 实现 MethodReplacer 接口的bean name * @see MethodReplacer */privatefinalStringmethodReplacerBeanName; /** * 标签 arg-type 数据 */privatefinalList<String> typeIdentifiers = newLinkedList<>();
- 一个例子
<?xml version="1.0" encoding="UTF-8"?> <beansxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://www.springframework.org/schema/beans"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <beanid="apple"class="org.source.hot.spring.overview.ioc.bean.lookup.Apple"> <replaced-methodreplacer="methodReplacerApple"name="hello" > <arg-type>String</arg-type> </replaced-method> </bean> <beanid="methodReplacerApple"class="org.source.hot.spring.overview.ioc.bean.lookup.MethodReplacerApple"> </bean> </beans>
methodReplacerBeanName 对应org.springframework.beans.factory.support.MethodReplacer
的实现类
typeIdentifiers 对应标签 arg-type 的属性值
构造方法
publicReplaceOverride(StringmethodName, StringmethodReplacerBeanName) { super(methodName); Assert.notNull(methodName, "Method replacer bean name must not be null"); this.methodReplacerBeanName = methodReplacerBeanName; }
methodName 通过父类进行设置
@Overridepublicbooleanmatches(Methodmethod) { // 方法名称是否相同if (!method.getName().equals(getMethodName())) { returnfalse; } // 是否重载if (!isOverloaded()) { // Not overloaded: don't worry about arg type matching...returntrue; } // If we get here, we need to insist on precise argument matching...// 类型标识数量是否和参数列表是否不相同if (this.typeIdentifiers.size() != method.getParameterCount()) { returnfalse; } // 获取参数类型列表Class<?>[] parameterTypes = method.getParameterTypes(); for (inti = 0; i < this.typeIdentifiers.size(); i++) { Stringidentifier = this.typeIdentifiers.get(i); // 判断 方法参数的类型是否在类型标识列表中if (!parameterTypes[i].getName().contains(identifier)) { returnfalse; } } returntrue; }
org.springframework.beans.factory.support.MethodOverrides
重载方法对象
存储所有重载的方法列表(set 结构)
privatefinalSet<MethodOverride> overrides = newCopyOnWriteArraySet<>();
几个方法
添加 MethodOverride
publicvoidaddOverride(MethodOverrideoverride) { this.overrides.add(override); } publicvoidaddOverrides(@NullableMethodOverridesother) { if (other != null) { this.overrides.addAll(other.overrides); } }
获取 MethodOverride
@NullablepublicMethodOverridegetOverride(Methodmethod) { MethodOverridematch = null; for (MethodOverridecandidate : this.overrides) { if (candidate.matches(method)) { match = candidate; } } returnmatch; }