Method Injection was introduced in Spring 1.1, which comes in two loosely related forms, Lookup Method Injection and Method Replacement.
Lookup Method Injection
It's added to overcome the problems encountered when a bean depends on another bean with a different lifecycle - specifically, when a singleton depends on a non-singleton.
Here's an example, we create one non-singleton bean and two singleton beans that both implement the same interface. One of the singletons obtains an instance of the non-singleton bean using "traditional" setter injection; the other uses Method Injection.
java: non-singleton bean
- public class MyHelper {
-
- public void doSomethingHelpful() {
-
- }
- }
java: this interface will be implemented by two singleton beans
- public interface DemoBean {
-
- public MyHelper getMyHelper();
- public void someOperation();
- }
java: traditional singleton bean
- public class StandardLookupDemoBean implements DemoBean {
-
- private MyHelper helper;
-
- public void setMyHelper(MyHelper helper) {
- this.helper = helper;
- }
-
- public MyHelper getMyHelper() {
- return this.helper;
- }
-
- public void someOperation() {
- helper.doSomethingHelpful();
- }
- }
java: method injection bean
- public abstract class AbstractLookupDemoBean implements DemoBean {
-
- public abstract MyHelper getMyHelper();
-
- public void someOperation() {
- getMyHelper().doSomethingHelpful();
- }
- }
xml: configuration file
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
- "http://www.springframework.org/dtd/spring-beans.dtd">
- <beans>
- <bean id="helper" class="MyHelper"
- singleton="false"/>
- <bean id="abstractLookupBean"
- class="AbstractLookupDemoBean">
- <lookup-method name="getMyHelper" bean="helper"/>
- </bean>
- <bean id="standardLookupBean"
- class="StandardLookupDemoBean">
- <property name="myHelper">
- <ref local="helper"/>
- </property>
- </bean>
- </beans>
Use Method Lookup Injection when you're working with beans of different lifecycles rather than implementing BeanFactoryAware and performing the lookup manually. Using Method Lookup Injection, you can keep your beans decoupled from Spring without any noticeable performance loss.
Although you don't have to make your lookup method abstract, doing so prevents you from forgetting to configure the lookup method and then using a blank implementation by accident.
Method Replacement
Using method replacement, you can replace the implementation of any method on any beans arbitrarily without having to change the source of the bean you are modifying.
Internally you achieve this by creating a subclass of the bean class dynamically. You use CGLIB and redirect calls to the method you want to replace to another bean that implements the MethodReplace interface.
java: any one of the two formatMessage methods can be replaced
- public class ReplacementTarget {
-
- public String formatMessage(String msg) {
- return "<h1>" + msg + "</h1>";
- }
-
- public String formatMessage(Object msg) {
- return "<h1>" + msg + "</h1>";
- }
- }
java: method replacer class, must implement MethodReplacer interface
- public class FormatMessageReplacer implements MethodReplacer {
-
- public Object reimplement(Object target, Method method, Object[] args)
- throws Throwable {
-
- if (isFormatMessageMethod(method)) {
-
- String msg = (String) args[0];
- return "<h2>" + msg + "</h2>";
- } else {
- throw new IllegalArgumentException("Unable to reimplement method "
- + method.getName());
- }
- }
-
- private boolean isFormatMessageMethod(Method method) {
-
-
- if (method.getParameterTypes().length != 1) {
- return false;
- }
-
- if (!("formatMessage".equals(method.getName()))) {
- return false;
- }
-
- if (method.getReturnType() != String.class) {
- return false;
- }
-
- if (method.getParameterTypes()[0] != String.class) {
- return false;
- }
- return true;
- }
- }
xml: mind the replaced-method portion
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
- "http://www.springframework.org/dtd/spring-beans.dtd">
- <beans>
- <bean id="methodReplacer"
- class="FormatMessageReplacer"/>
- <bean id="replacementTarget"
- class="ReplacementTarget">
- <replaced-method name="formatMessage" replacer="methodReplacer">
- <arg-type>String</arg-type>
- </replaced-method>
- </bean>
- <bean id="standardTarget"
- class="ReplacementTarget"/>
- </beans>
java: testing code piece
- public class MethodReplacementExample {
-
- public static void main(String[] args) {
- BeanFactory factory = new XmlBeanFactory(new FileSystemResource(
- "./replacement.xml"));
-
- ReplacementTarget replacementTarget =
- (ReplacementTarget) factory.getBean("replacementTarget");
- ReplacementTarget standardTarget =
- (ReplacementTarget) factory.getBean("standardTarget");
-
- displayInfo(replacementTarget);
- displayInfo(standardTarget);
- }
-
- private static void displayInfo(ReplacementTarget target) {
- System.out.println(target.formatMessage("Hello World!"));
-
- StopWatch stopWatch = new StopWatch();
- stopWatch.start("perfTest");
-
- for (int x = 0; x < 1000000; x++) {
- String out = target.formatMessage("foo");
- }
-
- stopWatch.stop();
-
- System.out.println("1000000 invocations took: "
- + stopWatch.getTotalTimeMillis() + " ms");
- }
- }
result:
<h2>Hello World!</h2>
1000000 invocations took: 3609 ms
<h1>Hello World!</h1>
1000000 invocations took: 844 ms
We still prefer to use standard Java mechanisms for overriding methods rather than depending on runtime bytecode enhancement. If you're going to use it, the recommendation is to use one MethodReplacer per method or group of overloaded methods. Avoid the temptation to use a single MethodReplacer for lots of unrelated methods; this results in lots of unnecessary String comparisons.
分享到:
相关推荐
SUMMARY OF SLAB INVENTORY STATUS(表格模板、XLS格式).XLS
### 关于《Too Much Too Soon》的综合分析与解读 #### 概述 《Too Much Too Soon》一文探讨了当前社会中一个普遍存在的现象:家长为了让孩子在起跑线上不落后,纷纷提供大量的课外学习机会,试图提前激发孩子的...
(Summary of Vue Interview Questions) # vue 面试题汇总 1、active-class 是哪个组件的属性?嵌套路由怎么定义 (1)、active-class 是 vue-router 模块的 router-link 组件的属性 (2)、使用 children 定义嵌套路由 ...
Furthermore, in Pivotal Certified Professional Spring Developer Exam: A Study Guide each chapter contains a brief study summary and question set, and the book’s free downloadable source code package ...
Praise for the Third Edition of Spring in Action Preface Acknowledgments About this Book 1. Core Spring Chapter 1. Springing into action 1.1. Simplifying Java development 1.1.1. Unleashing the power ...
Summary of Slab Inventory Status.xls
CS_OMP Summary of this function,正交匹配追踪法子函数
Summary A developer-focused guide to writing applications using Spring Boot. You'll learn how to bypass the tedious configuration steps so that you can concentrate on your application's behavior. ...
这篇文章是《HLA Evolved – A Summary of Major Technical Improvements》的原文,它最初发表于2008年欧洲交互仿真论坛学报,并获SISO “2008 Fall SIWzie”奖,它的作者有Björn Möller(Pitch公司的CTO及创始人...
Summary Dependency Injection Principles, Practices, and Patterns teaches you to use DI to reduce hard-coded dependencies between application components. You'll start by learning what DI is and what ...
机器学习技法15 - 4 - Summary of Extraction Models (9-12).mp4
fomc-summary-of-economic-projections-for-the-growth-rate-of-real-gross-domestic-product-central-tendency-midpoint_metadata.json fomc-summary-of-economic-projections-for-the-personal-consumption-...
17. Spring Beans and Dependency Injection 18. Using the @SpringBootApplication Annotation 19. Running Your Application 19.1. Running from an IDE 19.2. Running as a Packaged Application 19.3. Using the...
VBA Unity
【标题】"summary of fixed" 暗示了这是一个关于修复问题或优化代码的主题,可能是对某个软件或系统中已解决的问题的总结。由于没有直接的描述内容,我们需要结合标签和提供的链接来推测主题。 【标签】"源码" 和 ...
my one page study summary of jQuery framework
(多媒体技术与Director概述) 值得一看哟!!
So, here is my, yet unpolished implementation of the IEEE paper "A NEW EFFICIENT ELLIPSE DETECTION METHOD", Yonghong Xie & Qiang Ji 2002. \note Minor Customization have been added so as to improve ...