• 3.5 spring-replaced-method 子元素的使用与解析


    1.replaced-method 子元素

      方法替换: 可以在运行时用新的方法替换现有的方法,与之前的 look-up不同的是replace-method 不但可以动态地替换返回的实体bean,而且可以动态的更改原有方法的逻辑,

    1.1.1使用实例:

      首先创建一个Bean完成某项业务

    1 public class Person {
    2 
    3     public void show() {
    4         System.out.println("I am Person ..");
    5     }
    6 }

      在运营一段时间后需要改变原有的逻辑

     1 import java.lang.reflect.Method;
     2 
     3 import org.springframework.beans.factory.support.MethodReplacer;
     4 
     5 public class ReplacedClass implements MethodReplacer {
     6 
     7     @Override
     8     public Object reimplement(Object obj, Method method, Object[] args) throws Throwable {
     9         System.out.println(obj);
    10         System.out.println(method.getName());
    11         System.out.println("I am replacer...");
    12         return null;
    13     }
    14 
    15 }

    XML 如下

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    
        <bean id="person" class="test.replaced.Person">
            <replaced-method name="show" replacer="replace"></replaced-method>
        </bean>
        <bean id="replace" class="test.replaced.ReplacedClass">
        </bean>
    </beans> 

    测试类

     1 public class Main {
     2 
     3     public static String XML_PATH = "test\replaced\applicationContxt.xml";
     4 
     5     public static void main(String[] args) {
     6         try {
     7             Resource resource = new ClassPathResource(XML_PATH);
     8             XmlBeanFactory beanFactory = new XmlBeanFactory(resource);
     9             Person bean = (Person) beanFactory.getBean("person");
    10             System.out.println(bean);
    11             bean.show();
    12         }
    13         catch (Exception e) {
    14             e.printStackTrace();
    15         }
    16     }
    17 }

    好了,运行测试就可以看到我们预期的结果了,控制台成功打印出

    test.replaced.Person$$EnhancerBySpringCGLIB$$7f7813f2@1a69b07
    test.replaced.Person$$EnhancerBySpringCGLIB$$7f7813f2@1a69b07
    show
    I am replacer...

    知道了这个子元素的用法,我们再来看看Spring是怎么对这个元素进行提取的.

      BeanDefinitionParserDelegate.java

     1     /**
     2      * Parse replaced-method sub-elements of the given bean element.
     3      */
     4     public void parseReplacedMethodSubElements(Element beanEle, MethodOverrides overrides) {
     5         NodeList nl = beanEle.getChildNodes();
     6         for (int i = 0; i < nl.getLength(); i++) {
     7             Node node = nl.item(i);
     8             //仅当在Spring默认Bean的子元素下,
     9             //且为<lookup-method 时有效
    10             if (isCandidateElement(node) && nodeNameEquals(node, REPLACED_METHOD_ELEMENT)) {
    11                 Element replacedMethodEle = (Element) node;
    12                 // 提取要替换的旧的方法
    13                 String name = replacedMethodEle.getAttribute(NAME_ATTRIBUTE);
    14                 // 提取对应的新的替换的方法
    15                 String callback = replacedMethodEle.getAttribute(REPLACER_ATTRIBUTE);
    16                 ReplaceOverride replaceOverride = new ReplaceOverride(name, callback);
    17                 // Look for arg-type match elements.
    18                 List<Element> argTypeEles = DomUtils.getChildElementsByTagName(
    19                         replacedMethodEle, ARG_TYPE_ELEMENT);
    20                 for (Element argTypeEle : argTypeEles) {
    21                     String match = argTypeEle.getAttribute(ARG_TYPE_MATCH_ATTRIBUTE);
    22                     // 记录参数
    23                     match = (StringUtils.hasText(match) ? match
    24                             : DomUtils.getTextValue(argTypeEle));
    25                     if (StringUtils.hasText(match)) {
    26                         replaceOverride.addTypeIdentifier(match);
    27                     }
    28                 }
    29                 replaceOverride.setSource(extractSource(replacedMethodEle));
    30                 overrides.addOverride(replaceOverride);
    31             }
    32         }
    33     }

      我们可以看到,无论是lookup-method 还是 replace-method 都是构造了一个methodOverride ,并且最终记录在AbstractBeanDefinition 中的 methodOerrides 属性当中.

    而这个属性如何使用,我们后续再继续研究.

     

  • 相关阅读:
    Oracle中模拟SQL中的isnull函数
    Delphi:在OnBeforePost事件中取消TDataSet.Post(Delphi: Canceling a TDataSet.Post in an OnBeforePost Event)
    DBGrid的输入焦点控制
    刷新dbgrid 而不失去当前行位置
    MoveTo和MoveBy
    接口及接口测试
    ()文献可视化--vosviewer入门
    给出先序和中序,给一个数找到位置并输出它左子树里最大的数
    Kruskal算法:最小生成树
    Prim算法:最小生成树
  • 原文地址:https://www.cnblogs.com/mjorcen/p/3647234.html
Copyright © 2020-2023  润新知