Skip to content

allow replaced-method 'arg-type' matches against element body as well as 'match' attribute [SPR-9812] #14445

@spring-projects-issues

Description

@spring-projects-issues

Debabrata Patnaik opened SPR-9812 and commented

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


Affects: 3.1.1

Reference URL: http://www.coderanch.com/t/592323/Spring/Method-Replacer-concept-Spring

Sub-tasks:

0 votes, 5 watchers

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions