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 属性当中.

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

 

转载于:https://my.oschina.net/u/1590001/blog/268212

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值