IOC准确的说是一种思想,它能将你从繁琐的代码中解脱出来并专注于对象本身。进一步突出面向对象。
在了解IOC之前有必要了解依赖注入(DI)
例如要设计一个行李箱。
上面的设计看似完美,其实是存在问题的,如果现在根据市场需求要改变轮子的大小,那么整个架构都需要改变。
可以看到如果尺寸改变每个依赖类都需要改变,这对某些底层类被上千个类依赖来说,修改起来就是一场噩梦。
但是如果这样设计的话,修改轮子尺寸不需要改其他类。
如果按照以上设计的话,采用构造函数依赖注入(可采用其他方式注入例如:set注入、接口注入、注解注入)每次修改轮子的大小不需要动到其它类。
这样的好处还有:
可以协同工作,每个模块分给不同的人去完成,各自测试只需要构造自己所需要的类即可。
依赖倒置原则、IOC、DO、IOC容器的关系。
其核心思想就是高层模块不应该依赖底层模块,应该依赖其抽象。
IOC容器
1、管理者Bean的生命周期
2、控制着Bean的依赖注入。
3、创建实例的时候需要了解其中的细节
从下图中可以看出,IOC container设计行李箱的例子中是反过来的,从最下层开始查找依赖关系,查找到之后一步一步再new。采用依赖注入的设计像是一个深度优先遍历的方式实现,
IOC container可以隐藏实例的创建细节,蓝色部分可以看做一个工厂,我们就像一个客户,需要有一个luggage实例,不需要知道该实例是一步一步如何被创建的。实际项目中,有的service是好多年前写的,有几百个类作为其底层支撑,如果我们新开发一个功能,需要实例化service,是不需要搞清楚该service是如何实现的,直接入住service即可,这降低开发难度。
应用程序调用Bean的流程图大致如此。
1、读取Bean的配置信息到Spring 容器中
2、根据容器中的Bean注册表实例化Bean
3、将Bean实例以及其依赖关系放人Spring容器中去(利用java的反射功能JdkDynamicAopProxy)
4、供AP使用
Spring的IOC容器最大的亮点是
依赖注入和自动装配
源码类:BeanDefinitionRegistry
该接口提供了IOC容器注册BeanDefinition对象的方法。
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(256);
将解析到Bean以BeanName为key以BeanDef为value存入map中。
Spring 中最核心的接口?
BeanFactory
1、提供了IOC的配置机制
2、包含Bean的各种定义,便于实例Bean
3、建立Bean之间的依赖关系
4、Bean的生命周期
BeanFactory 的体系结构
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package org.springframework.beans.factory; import org.springframework.beans.BeansException; import org.springframework.core.ResolvableType; public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; Object getBean(String var1) throws BeansException;//按name匹配 <T> T getBean(String var1, Class<T> var2) throws BeansException; <T> T getBean(Class<T> var1) throws BeansException; //按类型匹配 Object getBean(String var1, Object... var2) throws BeansException; <T> T getBean(Class<T> var1, Object... var2) throws BeansException; boolean containsBean(String var1); boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;//单例模式 boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;//创建一个新的而不是从容器中查 boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException; Class<?> getType(String var1) throws NoSuchBeanDefinitionException; String[] getAliases(String var1); }
BeanFactory和applicationcontext的比较
1、BeanFactory是spring的基础设施,面向spring
2、applicationcontext面向spring框架的开发者
beanfactory类似于汽车发动机,applicationcontext则是一个完整的汽车。
applicationcontext堪称超级容器,继承多个接口。
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver
1、继承乐Beanfactory:能够管理 装配Bean
2、ResourcePatternResolver 加载资源文件。
3、ApplicationEventPublisher 能够注册监听器,实时监听机制。
UML图如下(IDEA中右击类名有个diagrams中可以查看,这个堪称学习源代码神器)