Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-9812

allow replaced-method 'arg-type' matches against element body as well as 'match' attribute

    Details

      Description

      Hi I had been trying to figure out the actual working of the messageReplacer in Spring. It seems the configuration file <arg-type>int</arg-type> is not having any impact on providing restriction for the replacement. All the methods gets replaced instead of specific method with the argument type matching the datatype mentioned in <arg-type>int</arg-type>.

      ReplacementTarget.java

      package com.doogle.spring.chapter4.mi;

      /** 
      * @author DOOGLE 
      * 
      */ 
      public class ReplacementTarget { 
      public int formatMessage(int a) 
      { 
      return 100000 + a + 100000; 
      } 
      public String formatMessage(String msg) 
      { 
      return "<h4>" + msg + "</h4>"; 
      } 
      } 

      FormatMessageReplacer.java

      package com.doogle.spring.chapter4.mi; 
       
      import java.lang.reflect.Method; 
       
      import org.springframework.beans.factory.support.MethodReplacer; 
       
      /** 
      * @author DOOGLE 
      * 
      */	
      public class FormatMessageReplacer implements MethodReplacer{ 
      public Object reimplement (Object arg0,Method method,Object [] args) throws Throwable 
      { 
      if(method.getReturnType() == int.class) 
      { 
      return (int)(Integer)args[0]; 
      } 
      else if (method.getReturnType() == String.class) 
      { 
      return (String)args[0]; 
      } 
      else 
      return "NA"; 
      /* 
      As expected, the output from the replacementTarget bean reflects the overridden implementation 
      that the MethodReplacer provides. Interestingly, though, the dynamically replaced method is more than 
      three times slower than the statically defined method. Removing the check for a valid method in the 
      MethodReplacer made a negligible difference across a number of executions, so we can conclude that 
      most of the overhead is in the CGLIB subclass 
       
      */ 
      } 
      } 

      replacement.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-3.1.xsd"> 
       
      <bean id="methodReplacer" class="com.doogle.spring.chapter4.mi.FormatMessageReplacer"/> 
       
      <bean id="replacementTarget" class="com.doogle.spring.chapter4.mi.ReplacementTarget"> 
      <replaced-method name="formatMessage" replacer="methodReplacer"> 
      <arg-type>int</arg-type> 
      </replaced-method> 
      </bean> 
       
      <bean id="standardTarget" class="com.doogle.spring.chapter4.mi.ReplacementTarget"/> 
       
      </beans>

      MethodReplacementExample.java

      /** 
      * 
      */ 
      package com.doogle.spring.chapter4.mi; 
       
      import org.springframework.context.support.GenericXmlApplicationContext; 
      import org.springframework.util.StopWatch; 
       
      /** 
      * @author DOOGLE 
      * 
      */ 
      public class MethodReplacementExample { 
      public static void main(String[] args) { 
      GenericXmlApplicationContext ctx = new GenericXmlApplicationContext(); 
      ctx.load("classpath:replacement.xml"); 
      ctx.refresh(); 
      ReplacementTarget replacementTarget = (ReplacementTarget)ctx.getBean("replacementTarget"); 
      ReplacementTarget standardTarget = (ReplacementTarget)ctx.getBean("standardTarget"); 
      displayInfo(replacementTarget); 
      displayInfo(standardTarget); 
      } 
      private static void displayInfo(ReplacementTarget replacementTarget) 
      { 
      System.out.println(replacementTarget.formatMessage(2)); 
      System.out.println(replacementTarget.formatMessage("2")); 
      //	 System.out.println(replacementTarget.formatMessage("Formating message and checking for message replacement")); 
      StopWatch stopWatch = new StopWatch(); 
      stopWatch.start("perfTesting"); 
      //	 Object obj = new Object(); 
      for(int i=0;i<1000000 ; i++) 
      { 
      String out = replacementTarget.formatMessage("foo-bar"); 
      } 
      stopWatch.stop(); 
      System.out.println("1000000 invocations took: " + stopWatch.getTotalTimeMillis()+ " ms"); 
      } 
      } 

      Based on my understanding the replacement should work on when the argument type is int. Not when we have the argument type as String.
      I tried changing the same in configuration file. Once you write <arg-type> the irrespective of the value you have the method getting replaced.
      I gave the value asd for the arg-type still the method got replaced. Can anyone explain how to restrict method replacement in spring.

      P.S. The code samples are based on the contents provided in the book
      Apress Pro Spring 3 by Clarence Ho and Rob Harrop

        Activity

        Hide
        gid79 Gareth Davis added a comment -

        if you change:

        <arg-type>int</arg-type>

        to:

        <arg-type match="int"/>

        you should have more joy.

        Show
        gid79 Gareth Davis added a comment - if you change: <arg-type>int</arg-type> to: <arg-type match="int"/> you should have more joy.
        Hide
        gid79 Gareth Davis added a comment -

        I've created a pull request for this issue:

        https://github.com/SpringSource/spring-framework/pull/153

        please ignore the closed #152 pull request, the above has the correct headers/copyrights etc

        Show
        gid79 Gareth Davis added a comment - I've created a pull request for this issue: https://github.com/SpringSource/spring-framework/pull/153 please ignore the closed #152 pull request, the above has the correct headers/copyrights etc
        Hide
        debu999 Debabrata Patnaik added a comment -

        Thanks for the information, Gareth.

        Show
        debu999 Debabrata Patnaik added a comment - Thanks for the information, Gareth.
        Hide
        debu999 Debabrata Patnaik added a comment -

        Thanks a lot Spring Team. Its really nice to see such quick response. We together can make Spring the best Programming Platform.

        Show
        debu999 Debabrata Patnaik added a comment - Thanks a lot Spring Team. Its really nice to see such quick response. We together can make Spring the best Programming Platform.
        Hide
        cbeams Chris Beams added a comment -

        commit 0709c033a01dd4a88720da41d4acb71abcd1e27b
        Author: Gareth Davis <[email protected]>
        Commit: Phillip Webb <[email protected]>
         
            Allow 'arg-type' matches against element body
            
            Allow the body of 'arg-type' XML elements to be used as an alternative to
            'match' attribute when defining a 'replace-method' in XML configuration.
            
            This change has been introduced primarily to support the samples printed
            in the Apress 'Pro Spring' book.
            
            Issue: SPR-9812

        Show
        cbeams Chris Beams added a comment - commit 0709c033a01dd4a88720da41d4acb71abcd1e27b Author: Gareth Davis <[email protected]> Commit: Phillip Webb <[email protected]>   Allow 'arg-type' matches against element body Allow the body of 'arg-type' XML elements to be used as an alternative to 'match' attribute when defining a 'replace-method' in XML configuration. This change has been introduced primarily to support the samples printed in the Apress 'Pro Spring' book. Issue: SPR-9812

          People

          • Assignee:
            pwebb Phil Webb
            Reporter:
            debu999 Debabrata Patnaik
            Last updater:
            Chris Beams
          • Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:
              Days since last comment:
              5 years, 4 weeks, 5 days ago