Java学习笔记-对IoC(Inversion of Control)的基本认识
目录基本认识实例自己的感悟基本认识Ioc:Inversion of Control 控制反转、依赖注入控制:控制对象(Java Bean)的创建以及销毁(生命周期)反转:将对象的控制权交给IoC容器下面例子围绕这三点:1. 所有的Bean的生命周期交由IoC容器管理;2. 所有被依赖的Bean通过...
·
目录
基本认识
Ioc:Inversion of Control 控制反转、依赖注入
控制:控制对象(Java Bean)的创建以及销毁(生命周期)
反转:将对象的控制权交给IoC容器
下面例子围绕这三点:
1. 所有的Bean的生命周期交由IoC容器管理;
2. 所有被依赖的Bean通过构造方法执行注入;
3. 被依赖的Bean需要优先创建;
实例
程序的运行截图如下:
Audi是张三开的,Buick是李四开的!
程序结构如下:
源码如下:
Audi.java
package ioc.demo.IocDemo.car;
public class Audi implements Car {
public void start(){
System.out.println("Audi. start");
}
public void turnLeft(){
System.out.println("Audi. turnLeft");
}
public void turnRight(){
System.out.println("Audi. turnRight");
}
public void stop(){
System.out.println("Audi. stop");
}
}
buick.java
package ioc.demo.IocDemo.car;
public class Buick implements Car {
public void start(){
System.out.println("Buick. start");
}
public void turnLeft(){
System.out.println("Buick. turnLeft");
}
public void turnRight(){
System.out.println("Buick. turnRight");
}
public void stop(){
System.out.println("Buick. stop");
}
}
Car.java
package ioc.demo.IocDemo.car;
public interface Car {
public void start();
public void turnLeft();
public void turnRight();
public void stop();
}
Humen.java
package ioc.demo.IocDemo.humen;
public interface Humen {
public void goHome();
}
HumenWithCar.java
package ioc.demo.IocDemo.humen;
import ioc.demo.IocDemo.car.Car;
public abstract class HumenWithCar implements Humen{
protected Car car;
public HumenWithCar(Car car){
this.car = car;
}
public abstract void goHome();
}
LiSi.java
package ioc.demo.IocDemo.humen;
import ioc.demo.IocDemo.car.Car;
public class LiSi extends HumenWithCar{
public LiSi(Car car) {
super(car);
}
@Override
public void goHome() {
car.start();
car.stop();;
}
}
ZhangSan.java
package ioc.demo.IocDemo.humen;
import ioc.demo.IocDemo.car.Car;
public class ZhangSan extends HumenWithCar{
public ZhangSan(Car car){
super(car);
}
@Override
public void goHome() {
car.start();
car.turnLeft();
car.turnRight();
car.stop();
}
}
IoCContainer.java
package ioc.demo.IocDemo;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
1. 实例化Bean
2. 保存bean
3. 提供bean
4. 每一个bean要产生一个唯一的id与之对应
*/
public class IoCContainer {
private Map<String, Object> beans = new ConcurrentHashMap<String, Object>();
/**
*根据beanId获取一个Bean
* @param beanId
* @return 返回bean
*/
public Object getBean(String beanId){
return beans.get(beanId);
}
/**
* 委托ioc容器创建一个bean
* @param clazz 要创建的bean的class
* @param beanId beanId
* @param paramBeanIds 要创建的bean的class的构造方法所需要的参数的beanId们
*/
public void setBeans(Class<?> clazz, String beanId, String... paramBeanIds){
//1. 组装构造方法所需要的参数值;
Object[] paramValues = new Object[paramBeanIds.length];
for (int i = 0; i < paramBeanIds.length; i++){
paramValues[i] = beans.get(paramBeanIds[i]);
}
//2. 调用构造方法实例化的bean;
Object bean = null;
for (Constructor<?> constructor : clazz.getConstructors()) {
try {
bean = constructor.newInstance(paramValues);
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
}
if(bean == null){
throw new RuntimeException("找不到合适的构造方法去实例化bean");
}
//3. 将实例化的bean放入beans;
beans.put(beanId, bean);
}
}
调用的代码:
package ioc.demo;
import ioc.demo.IocDemo.IoCContainer;
import ioc.demo.IocDemo.car.Audi;
import ioc.demo.IocDemo.car.Buick;
import ioc.demo.IocDemo.humen.Humen;
import ioc.demo.IocDemo.humen.LiSi;
import ioc.demo.IocDemo.humen.ZhangSan;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
private IoCContainer ioCContainer = new IoCContainer();
@Before
public void before(){ //创建Bean和使用Bean是两个不同的业务逻辑
ioCContainer.setBeans(Audi.class, "audi");
ioCContainer.setBeans(Buick.class, "Buick");
ioCContainer.setBeans(ZhangSan.class, "ZhangSan", "audi");
ioCContainer.setBeans(LiSi.class, "LiSi", "Buick");
ioCContainer.setBeans(Audi.class, "audi");
}
@Test
public void contextLoads() {
Humen zhangesan = (Humen) ioCContainer.getBean("ZhangSan");
zhangesan.goHome();
Humen liSi = (Humen) ioCContainer.getBean("LiSi");
liSi.goHome();
}
}
自己的感悟
这里发现一个东西,Java因为有反射机制,所以可以使用IoC的思想,实现控制翻转,依赖注入,这个是C++做不到的,在程序的逻辑结构,和设计上,这种方式的确是相当的好!
更多推荐
已为社区贡献20条内容
所有评论(0)