Spring的一个重要原理就是IOC(Inverse Of Control),即控制反转。IOC就是一种将组件依赖关系的创建和管理置于程序外部的技术,在Spring中Bean组件的实例化和依赖关系的管理控制都由Spring容器负责,对象与对象之间的关系可以简单的理解为对象之间的依赖关系:在 类 A 需要类 B 的一个实例来进行某些操作时,比如在类 A 的方法中需要调用类 B 的方法来完成功能,叫做类 A 依赖于类 B。依赖注入(DI:Dependency Injection) :两个对象之间的依赖关系在程序运行时由外部容器动态的注入依赖行为方式称为依赖注入
(DI) ,DI 是 IOC 的一种形式。IOC能够实现:你的类不会去查找或是实例化它们所依赖的类。控制恰好是反过来的,容器会设置这种依赖关系。使用 IoC 常常使代码更加简洁,并且为相互依赖的类提供一种很好的方法。
依赖注入的三种实现类型:构造器注入、Setter注入和接口注入。
1、构造器注入
依赖关系是通过类构造函数建立的,容器通过调用类的构造方法将其所需的依赖关系注入其中,例如在Spring的XML配置文件中,在构造Bean的时候使用<constructor-arg>元素来设置其依赖的对象。构造期间完成一个完整的、合法的对象。所有依赖关系在构造函数中集中呈现。依赖关系在构造时由容器一次性设定,组件被创建之后一直处于相对“不变”的稳定状态。只有组件的创建者关心其内部依赖关系,对调用者而言,该依赖关系处于“黑盒”之中。
<bean id="sonnet29" class="lucien.Sonnet29" /> <!-- 构造器注入 --> <bean id="poeticDuke" class="lucien.PoeticJuggler"> <constructor-arg value="15" /> <constructor-arg ref="sonnet29" /> </bean>
2、Setter方法注入
JavaBean的属性通常都是私有的,拥有一组存取器即:setXXX()和getXXX(),Spring就是通过使用属性的set方法来实现setter注入的。对于习惯了传统 javabean 开发的程序员,通过 setter 方法设定依赖关系更加直观。如果依赖关系较为复杂,那么构造注入模式的构造函数也会相当庞大,而此时setter注入模式则更为简洁。
package lucien; public interface Instrument { public void play(); }
package lucien; public class Saxophone implements Instrument { @Override public void play() { // TODO Auto-generated method stub System.out.println("Saxophone"); } }
package lucien; public class Instrumentalist implements Performer { private String song; private Instrument instrument; public String getSong() { return song; } public void setSong(String song) { this.song = song; } public Instrument getInstrument() { return instrument; } public void setInstrument(Instrument instrument) { this.instrument = instrument; } @Override public void perform() { // TODO Auto-generated method stub System.out.println("playing " + song + " : "); instrument.play(); } }
对应的配置文件部分如下:
<bean id="saxophone" class="lucien.Saxophone"/><bean id="Tim" class="lucien.Instrumentalist"><property name="song" value="Jingle Bells"/><property name="instrument" ref="saxophone"/></bean>
3、接口注入
在类中,对于依赖的接口,通过具体的实现类名,动态的加载并强制转换成其接口类型。接口注入不常用。
package lucien; public class Saxophone implements Instrument { @Override public void play() { // TODO Auto-generated method stub System.out.println("Saxophone"); } }
package lucien; public class Instrumentalist implements Performer { private String song; private Instrument instrument; public String getSong() { return song; } public void setSong(String song) { this.song = song; } @Override public void perform() { // TODO Auto-generated method stub System.out.println("playing " + song + " : "); try { instrument = (Instrument) Class.forName("lucien.Saxophone").newInstance(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } instrument.play(); } }