您的位置:首页 > 编程语言 > Java开发

[Spring]Method Injection

2016-04-14 12:57 555 查看
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();
}

@Bean
public CommandManager commandManager() {
return new CommandManager() {

@Override
protected Command createCommand() {
return attackCommand();
}
};
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: