spring IOC 剖析 再品IOC与DI
IOC(Inversion of Control) 控制反转:所谓控制反转,就是把原先我们代码里面需要实现的对象创 建、依赖的代码,反转给容器来帮忙实现。那么必然的我们需要创建一个容器,同时需要一种描述来让 容器知道需要创建的对象与对象的关系。这个描述最具体表现就是我们所看到的配置文件。
DI(Dependency Injection) 依赖注入:就是指对象是被动接受依赖类而不是自己主动去找,换句话说就 是指对象不是从容器中查找它依赖的类,而是在容器实例化对象的时候主动将它依赖的类注入给它。
上面是 ioc 和 DI 的通俗理解,我们也可以用我们现有的知识来思考这两点的实现,其实两者主要还是依赖与反射机制来实现这些功能,那么我们为了提出一些关键问题,来跟着关键问题来看下具体的流程。
在 spring 中对象之间的关系如何来表现
在我们配置文件中或者javaconfig中均又相应的方式来提现
描述对象之间关系的文件或者信息存在哪里
可能存在于classpat、fileSystem、url或者context中,
对于不同的存储位置和文件格式,其实的描述是不相同的,如何做到统一解析和声明
我们可以想一下,将这些外部的信息按照模型,进行转换,在内部维护一个统一的模型对象
如何对这些信息进行不同的解析
根据各自的特性指定相应的策略来进行解析
在 spring 中 BeanFactory 是顶层的容器接口,我们可以看出来其实 spring 中容器的本质就是工厂, 他有非常多的实现类,我们这里把主要的核心类图展示:
对上图做简单的说明:
BeanFactory 是顶层的容器接口,主要有三个子类接口 HierarchicalBeanFactory 、 AutowireCapableBeanFactory 、 ListableBeanFactory
在继承的关系中我们可以看到都是接口和抽象类为主,多层次的封装,最终的实现类如 DefaultListableBeanFactory ,还有类似 AbstractApplicationContext 的抽象子类,在spring中这些接口都有自己特定的使用场景,对每种场景中不同对象的创建传递到转化的过程中都进行了相应的控制限制,有很强的领域划分,职责单一可扩展性极强
public interface BeanFactory { /** * 主要勇于区分beanFactory与factoryBean,FactoryBean是spring内部生成对象的工厂即容器, * 在我们通过过getBean获取对象时得到的是真实对象的代理对象,如果我们要获取产生对象代理的 * 工厂则需要加该前缀 */ String FACTORY_BEAN_PREFIX = "&"; /** * 返回一个instance的实列 通过beanName */ Object getBean(String name) throws BeansException; /** * 通过BeanName与class类型来获取容器中的对象,多层限制校验 */ <T> T getBean(String name, Class<T> requiredType) throws BeansException; /** * 通过BeanName 同时指定相应的构造函数或者工厂方法的参数列表 */ Object getBean(String name, Object... args) throws BeansException; <T> T getBean(Class<T> requiredType) throws BeansException; <T> T getBean(Class<T> requiredType, Object... args) throws BeansException; <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType); <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType); /* * 校验是否在IOC中存在 */ boolean containsBean(String name); /* * 校验是单例或者原型模式 */ boolean isSingleton(String name) throws NoSuchBeanDefinitionException; boolean isPrototype(String name) throws NoSuchBeanDefinitionException; /* * 判断是IOC中bean的类型是否是typTomatch的类型 */ boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException; //获取指定bean的类型 @Nullable Class<?> getType(String name) throws NoSuchBeanDefinitionException; @Nullable Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException; // 获取bean的 别名 String[] getAliases(String name); }
在spring中 BeanFactory 定义了 容器的行为,但是并不会去实现这些,顶级接口制作了高度的抽象化处理,具体的容器的创建和运行们都是交给子类来实现,所以我们要知道IOC是如何运转的需要从spring中ico的实现子类来入门,如我们读取xml配置方式时的 ClasspathXmlApplicationContext 或者时在注解中使用的 AnnotationConfigApplicationContext 等,在这些具体的实现类中有容器初始化的具体流程
在上面类图中 ApplicationContext 类是非常重要的一个接口,这是spring提供的一个高级接口,也是我们以后接触最多的容器
2. BeanDefinition