[Spring]Method Injection

本文探讨了Spring框架中两种实现方法级别的依赖注入的方式。一种是通过实现ApplicationContextAware接口,在需要时手动获取Bean;另一种则是利用Spring的CGLIB动态代理技术,通过配置实现每次方法调用时都能获得一个新的实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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();
			}
		};
	}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值