8. Alternative method implementation of method injection
Spring
Provides a mechanism for replacing method implementations, allowing us to change bean
the implementation of a certain method. For example, we have one bean
, which has a add()
method that can be used to calculate the sum of two integers, but this time we want to change its implementation logic to multiply the two integers if they have the same value, otherwise, just multiply them In addition, we can Spring
achieve this requirement through the provided replacement method implementation mechanism without changing or unable to change the source code .
The core of the replacement method implementation mechanism is the MethodReplacer
interface, which defines a reimplement ()
method. The main logic of our replacement method implementation is implemented in this method. The specific definitions are as follows:
public interface MethodReplacer {
/**
* Reimplement the given method.
* @param obj the instance we're reimplementing the method for
* @param method the method to reimplement
* @param args arguments to the method
* @return return value for the method
*/Objectreimplement(Objectobj, Methodmethod, Object[] args) throwsThrowable;
}
We can see that reimplement()
the method will receive three parameters, which obj
represent the bean
object that method
needs to be replaced by the method, and the method that needs to be replaced args
represents the corresponding method parameters. For the previous example, suppose we have the following class definition corresponding bean
.
public class BeanA {
public int add(int a, int b) {
return a+b;
}
}
<bean id="beanA" class="com.app.BeanA"/>
If we need the implementation of the replacement add()
method to be multiplied when it is equal, and added otherwise, we can provide a corresponding implementation class for this method. The specific implementation is as follows.a
b
MethodReplacer
public class BeanAReplacer implements MethodReplacer {
/* *
* @param obj corresponds to the target object, ie beanA
* @param method corresponds to the target method, ie add
* @param args corresponds to the target parameter, ie a and b
*/ public Object reimplement ( Object obj , Method method , Object [] args )
throws Throwable {
Integer a = ( Integer )args[ 0 ];
Integer b = ( Integer )args[ 1 ];
if (a . equals(b)) {
return a
* b;
} else {
return a + b;
}
}
}
After that, you need to specify the method implementation to beanA
use BeanAReplacer
to replace when defining, which is specified by element. It requires two properties to be specified, and . Used to specify the name of the method that needs to be replaced, and is used to specify the corresponding one to replace . So, at this point we should define as follows:beanA
add()
replaced-method
name
replacer
name
replacer
MethodReplacer
bean
beanA
<bean id="beanAReplacer" class="com.app.BeanAReplacer"/>
<bean id="beanA" class="com.app.BeanA">
<replaced-method name="add" replacer="beanAReplacer"/>
</bean>
If MethodReplacer
the method to be replaced bean
belongs to the overloaded method in the corresponding method, that is, when there are multiple methods with the same method name, we also need to define the type of the corresponding method parameter through the replaced-method
element under the arg-type
element, so that we can distinguish Which method needs to be replaced. So, for the above example, we can also define as follows:
<bean id="beanAReplacer" class="com.app.BeanAReplacer"/>
<bean id="beanA" class="com.app.BeanA">
<replaced-method name="add" replacer="beanAReplacer">
<arg-type match="int"/>
<arg-type match="int"/>
</replaced-method>
</bean>
When there is only one method corresponding to the method name, it arg-type
will not work, that is, it will not be replaced Spring
according to the corresponding method at this time , or in other words, when there is only one method with the specified name, it can be defined no matter what. of.arg-type
replaced-method
arg-type
(Note: This article is written based on Spring 4.1.0)