Spring IoC контейнер: зависимости, инъекция метода, произвольная замена метода

Менее полезной формой внедрения метода, чем внедрением метода поиска, является возможность замены произвольных методов в управляемом компоненте другой реализацией метода.

С помощью метаданных конфигурации на основе XML вы можете использовать элемент replace-method, чтобы заменить существующую реализацию метода другой, для развернутого компонента. Рассмотрим следующий класс, в котором есть метод computeValue, который мы хотим переопределить:

Java

public class MyValueCalculator {

    public String computeValue(String input) {
        // некоторый реальный код...
    }

    // некоторые другие методы...
}

Kotlin

class MyValueCalculator {

    fun computeValue(input: String): String {
        // некоторый реальный код...
    }

    // некоторые другие методы...
}

Класс, который реализует интерфейс org.springframework.beans.factory.support.MethodReplacer, предоставляет определение нового метода, как показано в следующем примере:

Java

/**
 * предназначен для переопределения существующего computeValue(String)
 * реализация в MyValueCalculator
 */
public class ReplacementComputeValue implements MethodReplacer {

    public Object reimplement(Object o, Method m, Object[] args) throws Throwable {
        // получаем входное значение, работаем с ним и возвращаем вычисленный результат
        String input = (String) args[0];
        ...
        return ...;
    }
}

Kotlin

/**
* предназначен для переопределения существующего computeValue(String)
* реализация в MyValueCalculator
*/
class ReplacementComputeValue : MethodReplacer {

    override fun reimplement(obj: Any, method: Method, args: Array<out Any>): Any {
        // получаем входное значение, работаем с ним и возвращаем вычисленный результат
        val input = args[0] as String;
        ...
        return ...;
    }
}

Определение компонента для развертывания исходного класса и задание переопределения метода будет выглядеть следующим образом:

<bean id="myValueCalculator" class="x.y.z.MyValueCalculator">
    <!-- замена произвольного метода -->
    <replaced-method name="computeValue" replacer="replacementComputeValue">
        <arg-type>String</arg-type>
    </replaced-method>
</bean>

<bean id="replacementComputeValue" class="a.b.c.ReplacementComputeValue"/>

Вы можете использовать один или несколько элементов <arg-type/> внутри элемента <replace-method/>, чтобы указать сигнатуру переопределяемого метода. Подпись для аргументов необходима, только если метод перегружен и в классе существует несколько вариантов. Для удобства строка типа для аргумента может быть подстрокой полного имени типа. Например, следующие все соответствуют java.lang.String:

java.lang.String
String
Str

Поскольку количества аргументов часто достаточно, чтобы различать каждый возможный выбор, этот ярлык может сэкономить много времени на ввод текста, позволяя вводить только самую короткую строку, соответствующую типу аргумента.


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки