IoC, Inversion of Control,控制反转, 控制权从应用程序转移到IoC容器(如Spring)
IoC是一种通用的设计原则,而DI(Dependency Injection,依赖注入)则是具体的设计模式,它体现了IoC的设计原则,DI是IoC典型的实现。
IoC与DI的关系就好比Java中的”接口”和”接口的实现类”的关系一样。目前有四种DI实现:setter注入、构造器注入、接口注入和静态工厂注入,其中后两种应用较少。
setter注入
首先有个接口是Animal, Cat是Animal的实现类,有个AnimalAction的逻辑类。
Cat类如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public interface Animal { public void sayHello(); void setMsg(String msg); } public class Cat implements Animal { private String msg; public void setMsg(String msg){ this.msg = msg; } @Override public void sayHello(){ System.out.println(msg + ",喵~喵~"); } }
|
AnimalAction类如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class AnimalAction { private Animal animal; public void animalSayHello() { animal.sayHello(); } public void setAnimal(Animal animal) { this.animal = animal; } public AnimalAction(Animal animal) { this.animal = animal; } }
|
Spring-beans.xml配置如下:
1 2 3 4 5 6 7 8
| <beans> <bean id="animal" class="com.tw.hello.spring.Cat"> <property name="msg" value="猫猫" /> </bean> <bean id="animalAction" class="com.tw.hello.spring.AnimalAction"> <property name="animal" ref="animal"></property> </bean> </beans>
|
构造器注入
构造器注入的话,必须要在AnimalAction中加入有参构造方法。
Spring-beans.xml配置如下:
1 2 3 4 5 6 7 8
| <beans> <bean id="animal" class="com.tw.hello.spring.Cat"> <property name="msg" value="猫猫" /> </bean> <bean id="animalAction" class="com.tw.hello.spring.AnimalAction"> <constructor-arg index="0" ref="animal"></constructor-arg> </bean> </beans>
|
接口注入
在AnimalAction类中加入如下代码,并注释原来的setter注入和构造器注入方式。
1 2 3 4 5 6 7 8 9
| public void animalSayHello() { try { animal = (Animal) Class.forName("com.tw.hello.spring.Cat").newInstance(); animal.sayHello(); } catch (Exception e) { e.printStackTrace(); } }
|
静态工厂注入
此时我们再添加一个Anima的实现类Dog,类似于Cat
1 2 3 4 5 6 7 8 9 10 11
| public class Dog implements Animal { private String msg; public void setMsg(String msg){ this.msg = msg; } @Override public void sayHello(){ System.out.println(msg + ",旺~旺~"); } }
|
再添加AnimalFactory工厂,用于静态注入
1 2 3 4 5 6 7 8 9 10
| public class AnimalFactory { public static Animal getAnimal(String type) { if ("cat".equalsIgnoreCase(type)) { return new Cat(); } else { return new Dog(); } } }
|
Annotation方式
主要是用@Component和@Autowired来代替bean配置,只需要在入口XML文件中加入以下,便可以自动扫描注解。
1 2
| <context:component-scan base-package="com.thoughtworks.bookshelf"/> <context:annotation-config/>
|
其本质还是setter注入和构造器注入两种方式,如果在AnimalAction中,@Autowired放在字段上,就是setter注入;如果@Autowired放在构造方法上,则是构造器方式注入。