Ioc in Spring

Ioc in Spring

IOC (Inversion of Control)

控制反转是一种不同对象之间解耦合的机制. 一般在实际应用中分解为两种Dependency Injection和Dependency Lookup, 两者的实现也不一样. 两者的不同在于在Dependency Lookup中对象持有依赖对象的引用, 而Dependency Injection是由IOC容器负责在适当的时候把依赖对象注入到目标对象中的.

Dependency Lookup

Dependency Lookup一般也分为两种类型: Dependency pull, Contextualized Dependency Lookup.

Dependency Pull

就是把对象都注册到某一个registry上, 一般是一个JNDI Registry(可以认为是一个很大的xml), 在需要的时候容器会在适当的时候通过注册的key取出这个bean, 然后装配.

public class DependencyPull {
	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext
		("META-INF/spring/app-context.xml");

		MessageRenderer mr = ctx.getBean("renderer", MessageRenderer.class);
		mr.render();
	}
}
Contextualized Dependency Lookup

同Dependency Pull不同的是, Contextualized Dependency Lookup是由容器管理的, 不是注册到xml中的, 而是动态地注册到容器中的, 一般容器是由底层应用服务器或者是框架提供的.

例如注册到容器的组件应该实现某个搜索的方法:

public interface ManagedCompenet{
	void performLookup(Container container);
}

而容器需要有这样的接口:

public interface Container{
	Object getDependency(String key);
}

需要依赖对象时可以如下引用:

	public class ContextualizedDependencyLookup implements ManagedComponent {
	private Dependency dependency;

	@Override
	public void performLookup(Container container) {
		this.dependency = (Dependency) container.getDependency("myDependency");
	}

	@Override
	public String toString() {
		return dependency.toString();
	}
}

普通的开发会有生命周期的影响.
而IOC的核心就是生成和销毁都不由引用者本身管理, 而是由第三方管理, 最多的是数据库连接, 使用者不再需要管理数据库连接的生命周期. 如果用的不对, 则会引发异常.

Dependency Injection

也分为两种, Constructor Dependency Injection 和 Setter Dependency Injection.

public class ConstructorInjection {
	private Dependency dependency;

	public ConstructorInjection(Dependency dependency) {
		this.dependency = dependency;
	}
 	@Override
	public String toString() {
		return dependency.toString();
	}
}
public class SetterInjection {
	private Dependency dependency;

	public void setDependency(Dependency dependency) {
		this.dependency = dependency;
	}

	@Override
	public String toString() {
		return dependency.toString();
	}
}

Lookup和Injection两者之间的差别主要在于,对于lookup已经做到了解耦,但是还是需要在目标对象中通过操作或者实现接口得到依赖对象(代码更少,不是), 而Injection更彻底一些.
另一个特殊的好处是, 使用Injection更方便测试, 也可以使得测试和开发分离.

原文地址:https://www.cnblogs.com/putuotingchan/p/8630992.html