[Spring]Method Injection

来源:互联网 发布:常见的网络进攻形式 编辑:程序博客网 时间:2024/06/07 05:05

Spring-framwork 提供了一种基于方法级的注入方式

考虑一种情况,一个singleton A 和一个 prototype B,A中有一个方法每次执行的时候都需要一个B的实例,由于Spring容器在初始A的时候已经初始好一切,那么这个时候如何做到每次执行该方法的时候,提供一个依赖B呢?


解决有两种方法:

1.通过实现 ApplicationContextAware 接口,硬编码实现每次调用该方法的时候注入一个实例B,然而这种方法会使代码和注入过程耦合在一起

2.提供一个abstract方法,Spring使用CGLIB重写抽象方法提供注入 (Method Injection)

方法注入,提供了方法级的注入方式,保证每次执行到该方法的时候都会提供一个新的B实例来使用,由Spring容器通过配置完成解耦工作。


Command接口:

package com.interfaces;public interface Command {void setState(String commandState);String execute();}

Command实现:

package com.domain;import com.interfaces.Command;public class AttackCommand implements Command {private String commandState;private static int count = 0;private final int id = count++;public AttackCommand() {System.out.println("command init");}public String execute() {return "Attack Command " + id + ": starting attack " + commandState;}public void setState(String commandState) {this.commandState = commandState;}}


Method 1:

package com.domain;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import com.interfaces.Command;public class CoupleCommandManager implements ApplicationContextAware {private ApplicationContext applicationContext;public String process(String commandState) {Command command = createCommand();command.setState(commandState);return command.execute();}protected Command createCommand() {return applicationContext.getBean("attackCommand", Command.class);}public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}}



Method 2:

package com.domain;import com.interfaces.Command;public abstract class CommandManager {public String process(String commandState){Command command = createCommand();command.setState(commandState);return command.execute();}protected abstract Command createCommand();}

xml配置文件

<bean id="attackCommand" class="com.domain.AttackCommand" scope="prototype"/><bean id="coupleCommandManager" class="com.domain.CoupleCommandManager"></bean><bean id="commandManager" class="com.domain.CommandManager"><lookup-method name="createCommand" bean="attackCommand"/></bean>


java cfg:

 @Bean@Scope("prototype")public Command attackCommand() {return new AttackCommand();}@Beanpublic CommandManager commandManager() {return new CommandManager() {@Overrideprotected Command createCommand() {return attackCommand();}};}




1 0
原创粉丝点击