Spring MethodOverride
- Author: HuiFer
源码阅读仓库: SourceHot-spring
org.springframework.beans.factory.support.MethodOverrideorg.springframework.beans.factory.support.LookupOverrideorg.springframework.beans.factory.support.ReplaceOverride
org.springframework.beans.factory.support.MethodOverrides
MethodOverride
- MethodOverride 方法重载类
在MethodOverride定义了下面三个属性
- 方法名称
- 是否重载
- 源
public abstract class MethodOverride implements BeanMetadataElement {/*** 方法名称*/private final String methodName;/*** 是否重载*/private boolean overloaded = true;/*** 源*/@Nullableprivate Object source;}
- 定义了一个抽象方法, 交由子类实现
public abstract boolean matches(Method method);
类图

在 Spring 中有两种可以重写的机制(XML)
lookup-method标签<lookup-method name="" bean=""/>
replaced-method标签<replaced-method name="" replacer=""/>
相对应的两个类如类图所示
LookupOverride
org.springframework.beans.factory.support.LookupOverride- lookup-method 标签对应的实体对象
属性列表
- beanName
- method
@Nullableprivate final String beanName;@Nullableprivate Method method;
matches
比较方法
- method 是否直接相等
- method 名称是否相同
- 是否需要重载
- 是不是 ABSTRACT 方法
- 参数列表长度是否等于 0
@Overridepublic boolean matches(Method method) {if (this.method != null) {// 通过 equals 判断return method.equals(this.method);}else {// 1. method 名称是否相同// 2. 是否需要重载// 3. 是不是 ABSTRACT 方法// 4. 参数列表长度是否等于0return (method.getName().equals(getMethodName()) && (!isOverloaded() ||Modifier.isAbstract(method.getModifiers()) || method.getParameterCount() == 0));}}
ReplaceOverride
org.springframework.beans.factory.support.ReplaceOverride
/*** 实现 MethodReplacer 接口的bean name* @see MethodReplacer*/private final String methodReplacerBeanName;/*** 标签 arg-type 数据*/private final List<String> typeIdentifiers = new LinkedList<>();
- 一个例子
<?xml version="1.0" encoding="UTF-8"?><beans xmlns: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"><bean id="apple" class="org.source.hot.spring.overview.ioc.bean.lookup.Apple"><replaced-method replacer="methodReplacerApple" name="hello" ><arg-type>String</arg-type></replaced-method></bean><bean id="methodReplacerApple" class="org.source.hot.spring.overview.ioc.bean.lookup.MethodReplacerApple"></bean></beans>
methodReplacerBeanName 对应org.springframework.beans.factory.support.MethodReplacer 的实现类
typeIdentifiers 对应标签 arg-type 的属性值
构造方法
public ReplaceOverride(String methodName, String methodReplacerBeanName) {super(methodName);Assert.notNull(methodName, "Method replacer bean name must not be null");this.methodReplacerBeanName = methodReplacerBeanName;}
methodName 通过父类进行设置
matches
@Overridepublic boolean matches(Method method) {// 方法名称是否相同if (!method.getName().equals(getMethodName())) {return false;}// 是否重载if (!isOverloaded()) {// Not overloaded: don't worry about arg type matching...return true;}// If we get here, we need to insist on precise argument matching...// 类型标识数量是否和参数列表是否不相同if (this.typeIdentifiers.size() != method.getParameterCount()) {return false;}// 获取参数类型列表Class<?>[] parameterTypes = method.getParameterTypes();for (int i = 0; i < this.typeIdentifiers.size(); i++) {String identifier = this.typeIdentifiers.get(i);// 判断 方法参数的类型是否在类型标识列表中if (!parameterTypes[i].getName().contains(identifier)) {return false;}}return true;}
MethodOverrides
org.springframework.beans.factory.support.MethodOverrides重载方法对象
存储所有重载的方法列表(set 结构)
private final Set<MethodOverride> overrides = new CopyOnWriteArraySet<>();
几个方法
添加 MethodOverride
public void addOverride(MethodOverride override) {this.overrides.add(override);}public void addOverrides(@Nullable MethodOverrides other) {if (other != null) {this.overrides.addAll(other.overrides);}}
获取 MethodOverride
@Nullablepublic MethodOverride getOverride(Method method) {MethodOverride match = null;for (MethodOverride candidate : this.overrides) {if (candidate.matches(method)) {match = candidate;}}return match;}
