Skip to content

Latest commit

 

History

History
242 lines (183 loc) · 5.35 KB

Spring-MethodOverride.md

File metadata and controls

242 lines (183 loc) · 5.35 KB

Spring MethodOverride

  • 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 方法重载类

MethodOverride定义了下面三个属性

  1. 方法名称
  2. 是否重载
publicabstractclassMethodOverrideimplementsBeanMetadataElement { /** * 方法名称 */privatefinalStringmethodName; /** * 是否重载 */privatebooleanoverloaded = true; /** * 源 */@NullableprivateObjectsource; }
  • 定义了一个抽象方法, 交由子类实现
publicabstractbooleanmatches(Methodmethod);

类图

MethodOverride

  • 在 Spring 中有两种可以重写的机制(XML)

    1. lookup-method 标签

      <lookup-methodname=""bean=""/>
    2. replaced-method 标签

      <replaced-methodname=""replacer=""/>

相对应的两个类如类图所示

LookupOverride

  • org.springframework.beans.factory.support.LookupOverride
  • lookup-method 标签对应的实体对象

属性列表

  1. beanName
  2. method
@NullableprivatefinalStringbeanName; @NullableprivateMethodmethod;

matches

比较方法

  1. method 是否直接相等
  2. method 名称是否相同
  3. 是否需要重载
  4. 是不是 ABSTRACT 方法
  5. 参数列表长度是否等于 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)); } }

ReplaceOverride

  • 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 通过父类进行设置

matches

@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; }

MethodOverrides

  • org.springframework.beans.factory.support.MethodOverrides

  • 重载方法对象

  • 存储所有重载的方法列表(set 结构)

privatefinalSet<MethodOverride> overrides = newCopyOnWriteArraySet<>();

几个方法

  1. 添加 MethodOverride

    publicvoidaddOverride(MethodOverrideoverride) { this.overrides.add(override); } publicvoidaddOverrides(@NullableMethodOverridesother) { if (other != null) { this.overrides.addAll(other.overrides); } }
  2. 获取 MethodOverride

    @NullablepublicMethodOverridegetOverride(Methodmethod) { MethodOverridematch = null; for (MethodOverridecandidate : this.overrides) { if (candidate.matches(method)) { match = candidate; } } returnmatch; }
close