// a class that uses a stateful Command-style class to perform some processingpackagefiona.apple;// Spring-API importsimportorg.springframework.beans.BeansException;importorg.springframework.context.ApplicationContext;importorg.springframework.context.ApplicationContextAware;publicclassCommandManagerimplementsApplicationContextAware {privateApplicationContext applicationContext;publicObjectprocess(Map commandState) {// grab a new instance of the appropriate CommandCommand command =createCommand();// set the state on the (hopefully brand new) Command instancecommand.setState(commandState);returncommand.execute(); }protectedCommandcreateCommand() {// notice the Spring API dependency!returnthis.applicationContext.getBean("command",Command.class); }publicvoidsetApplicationContext(ApplicationContext applicationContext) throwsBeansException {this.applicationContext= applicationContext; }}
前面是不可取的,因为业务代码知道并耦合到 Spring 框架。方法注入是 Spring IoC 容器的一项高级功能,可让您干净地处理此用例。
在前面代码片段中的CommandManager类的情况下,Spring 容器会动态覆盖createCommand() 方法的实现。类CommandManager没有任何 Spring 依赖项,如重新设计的示例所示:
packagefiona.apple;// no more Spring imports!publicabstractclassCommandManager {publicObjectprocess(Object commandState) {// grab a new instance of the appropriate Command interfaceCommand command =createCommand();// set the state on the (hopefully brand new) Command instancecommand.setState(commandState);returncommand.execute(); }// okay... but where is the implementation of this method?protectedabstractCommandcreateCommand();}
<!-- a stateful bean deployed as a prototype (non-singleton) --><beanid="myCommand"class="fiona.apple.AsyncCommand"scope="prototype"><!-- inject dependencies here as required --></bean><!-- commandProcessor uses statefulCommandHelper --><beanid="commandManager"class="fiona.apple.CommandManager"> <lookup-methodname="createCommand"bean="myCommand"/></bean>
/** * meant to be used to override the existing computeValue(String) * implementation in MyValueCalculator */publicclassReplacementComputeValueimplementsMethodReplacer {publicObjectreimplement(Object o,Method m,Object[] args) throwsThrowable {// get the input value, work with it, and return a computed resultString input = (String) args[0];...return...; }}