一、IOC
“控制反转(IoC)”也称为“依赖注入(DI)”,是一个定义对象依赖的过程,对象只和 构造参数,工厂方法参数,对象实例属性或工厂方法返回相关。容器在创建这些 bean 的时 候注入这些依赖。这个过程是一个反向的过程,所以命名为依赖反转,对象实例的创建由其 提供的构造方法或服务定位机制来实现。
IOC 最大的好处就是“解耦”。
二、IOC底层原理使用技术
1、xml配置文件,dom4j解析配置的xml文件
2、注解处理。spring4 和spring boot 大量使用注解,简化了bean的配置。
3、工厂、策略、委托等设计模式
4、反射
5、动态代理(JDK自带动态代理(实现了接口的类)、CGLib(未实现接口的类))
三、Spring容器基本概念
Spring 通过一个配置文件描述 Bean 及 Bean 之间的依赖关系,利用 Java 语言的反射功能实例化 Bean 并建立 Bean 之间的依赖关系。 Spring 的 IoC 容器在完成这些底层工作的基础上,还提供了 Bean 实例缓存、生命周期管理、 Bean 实例代理、事件发布、资源装载等高级服务。
BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身;
ApplicationContext 面向使用 Spring 框架的开发者,几乎所有的应用场合我们都直接使用 ApplicationContext 而非底层的 BeanFactory。
BeanDefinition 是描述bean的类,容器通过一个Map持有BeanDefinition。
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(64);//key为beanName;
四、IOC demo
Spring的源码,看的出来,源码异常复杂,这是因为Spring的设计者需要考虑到框架的扩展性,健壮性,性能等待元素,因此设计的很复杂。
因此实现一个简单的 IOC,让我们更加深刻的理解IOC,因此,有了这篇文章。
当然我们是仿照Spring 的 IOC,因此代码命名和设计基本是仿照spring的。
我们将分为几步来编写简易 IOC,首先设计组件,再设计接口,然后关注实现。
BeanFactory
容器,BeanDefinition
Bean的基本数据结构,当然还需要加载Bean的资源加载器
。大概最重要的就是这几个组件。容器用来存放初始化好的Bean,BeanDefinition 就是Bean的基本数据结构,比如Bean的名称,Bean的属性 PropertyValue
,Bean的方法,是否延迟加载,依赖关系等。资源加载器就简单了,就是一个读取XML配置文件的类,读取每个标签并解析。
首先肯定需要一个BeanFactory,就是Bean容器,容器接口至少有2个最简单的方法,一个是获取Bean,一个注册Bean.
public interface BeanFactory {
/**
* 根据bean的名称从容器中获取bean对象
*
* @param name bean 名称
* @return bean实例
* @throws Exception 异常
*/
Object getBean(String name) throws Exception;
/**
* 将bean注册到容器中
*
* @param name bean 名称
* @param bean bean实例
* @throws Exception 异常
*/
void registerBeanDefinition(String name, BeanDefinition bean) throws Exception;
}
一个最简单 BeanDefinition 接口,我们为了方便,但因为我们这个不必考虑扩展,因此可以直接设计为类,BeanDefinition 需要哪些元素和方法呢? 需要一个 Bean 对象,一个Class对象,一个ClassName字符串,还需要一个元素集合 PropertyValues
public class BeanDefinition {
/**
* bean
*/
private Object bean;
/**
* bean 的 CLass 对象
*/
private Class beanClass;
/**
* bean 的类全限定名称
*/
private String ClassName;
/**
* 类的属性集合
*/
private PropertyValues propertyValues = new PropertyValues();
/**
* 获取bean对象
*/
public Object getBean() {
return this.bean;
}
/**
* 设置bean的对象
*/
public void setBean(Object bean) {
this.bean = bean;
}
/**
* 获取bean的Class对象
*/
public Class getBeanclass() {
return this.beanClass;
}
/**
* 通过设置类名称反射生成Class对象
*/
public void setClassname(String name) {
this.ClassName = name;
try {
this.beanClass = Class.forName(name);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取bean的属性集合
*/
public PropertyValues getPropertyValues() {
return this.propertyValues;
}
/**
* 设置bean的属性
*/
public void setPropertyValues(PropertyValues pv) {
this.propertyValues = pv;
}
}
一个容器实现:
public class AutowireBeanFactory extends AbstractBeanFactory {
/**
* 根据bean 定义创建实例, 并将实例作为key, bean定义作为value存放,并调用 addPropertyValue 方法 为给定的bean的属性进行注入
*/
@Override
protected Object doCreate(BeanDefinition beandefinition) throws Exception {
Object bean = beandefinition.getBeanclass().newInstance();
addPropertyValue(bean, beandefinition);
return bean;
}
/**
* 给定一个bean定义和一个bean实例,为给定的bean中的属性注入实例。
*/
protected void addPropertyValue(Object bean, BeanDefinition beandefinition) throws Exception {
// 循环给定 bean 的属性集合
for (PropertyValue pv : beandefinition.getPropertyValues().getPropertyValues()) {
// 根据给定属性名称获取 给定的bean中的属性对象
Field declaredField = bean.getClass().getDeclaredField(pv.getname());
// 设置属性的访问权限
declaredField.setAccessible(true);
// 获取定义的属性中的对象
Object value = pv.getvalue();
// 判断这个对象是否是 BeanReference 对象
if (value instanceof BeanReference) {
// 将属性对象转为 BeanReference 对象
BeanReference beanReference = (BeanReference) value;
// 调用父类的 AbstractBeanFactory 的 getBean 方法,根据bean引用的名称获取实例,此处即是递归
value = getBean(beanReference.getName());
}
// 反射注入bean的属性
declaredField.set(bean, value);
}
}
}
abstract class AbstractBeanFactory implements BeanFactory {
/**
* 容器
*/
private HashMap<String, BeanDefinition> map = new HashMap<>();
/**
* 根据bean的名称获取bean, 如果没有,则抛出异常 如果有, 则从bean定义对象获取bean实例
*/
@Override
public Object getBean(String name) throws Exception {
BeanDefinition beandefinition = map.get(name);
if (beandefinition == null) {
throw new IllegalArgumentException("No bean named " + name + " is defined");
}
Object bean = beandefinition.getBean();
if (bean == null) {
bean = doCreate(beandefinition);
}
return bean;
}
/**
* 注册 bean定义 的抽象方法实现,这是一个模板方法, 调用子类方法doCreate,
*/
@Override
public void registerBeanDefinition(String name, BeanDefinition beandefinition) throws Exception {
Object bean = doCreate(beandefinition);
beandefinition.setBean(bean);
map.put(name, beandefinition);
}
/**
* 减少一个bean
*/
abstract Object doCreate(BeanDefinition beandefinition) throws Exception;
}
github地址:IOC demo