2021-03-15——简述SpringIOC和DI的实现原理

简述SpringIOC和DI的实现原理

Inversion of Control,所谓控制反转,就是原先我们代码需要实现的对象创建、依赖的代码,反转给容器便忙实现。那就需要一个容器、一种描述需要创建的对象与对象的关系,这种描述最具体的表现就是我们的配置文件。

Dependency Injection,所谓依赖注入,被动接受依赖而不主动去找, 就是对象不是从容器中查找它依赖的类,而是在容器实例化对象的时候主动将它依赖的类注入给它。

对象和对象的关系怎么表示?

可以用xml、 properties文件等语义配置文件表示。

描述对象关系的文件存放在哪里?

可能是classpath、filesystem ,或者是 URL 网络资源, servletContext 等。

有了配置文件,那如何解析配置文件?

Spring核心容器类结构:

(1)BeanFactory:

Spring Bean 的创建是典型的工厂模式,这一系列的 Bean 工厂,也即 IOC 容器为开发者管理对象间的依赖关系提供了很多便利和基础服务,在 Spring 中有许多的 IOC 容器的实现供用户选择和使用,其相互关系如下:

其中BeanFactory 作为最顶层的一个接口类,它定义了 IOC 容器的基本功能规范, BeanFactory 有三个子类: ListableBeanFactory 、 Hierarc hicalBeanFactory 和 AutowireCapableBeanFactory 。但是从上图中我们可以发现最终的默认实现类是DefaultListableBeanFactory ,他实现了所有的接口。那为何要定义这么多层次的接口呢?查阅这些接口的源码和说明发现,每个接口都有他使用的场合,它主要是为了区分在 Spring 内部在操作过程中对象的传递和转化过程中,对对象的数据访问所做的限制。例如 ListableBeanFactory 接口表示这些 Bean 是可列表的,而 HierarchicalBeanFactory表示的是这些 Bean 是有继承关系的,也就是每个 Bean 有可能有父 Bean 。AutowireCapableBeanFactory 接口定义 Bean 的自动装配规则。这四个接口共同定义了 Bean 的集合、 Bean 之间的关系、以及 Bean 行为

最基本的IOC 容器接口 BeanFactory

public interface BeanFactory {

    //对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,
    // 如果需要得到工厂本身,需要转义
     String FACTORY_BEAN_PREFIX = "&";

    // 根据bean的名字,获取在IOC容器中得到bean实例
     Object getBean(String name) throws BeansException;

    // 根据bean的名字和Class类型来得到bean实例,增加了类型安全验证机制。
     <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;

     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;

    //提供对bean的检索,看看是否在IOC容器有这个名字的bean
     boolean containsBean(String name);

     //根据bean名字得到bean实例,并同时判断这个bean是不是单例
     boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
     boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
     boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
     boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

     //得到bean实例的Class类型
     @Nullable
     Class<?> getType(String name) throws NoSuchBeanDefinitionException;

     //得到bean的别名,如果根据别名检索,那么其原名也会被检索出来
     String[] getAliases(String name); 
     
}

在BeanFactory 里只对 IOC 容器的基本行为作了定义,根本不关心你的 Bean 是如何定义怎样加载的。正如我们只关心工厂里得到什么的产品对象,至于工厂是怎么生产这些对象的,这个基本的接口不关心。

而要知道工厂是如何产生对象的,我们需要看具体的 IOC 容器实现, Spring 提供了许 多 IOC 容器的实现。比如 XmlBeanFactory ClasspathXmlApplicationContext 等。其中 XmlBeanFactory就是针对最基本的 IOC 容器的实现,这个 IOC 容器可以读取 XML 文件定义的 BeanDefinition XML文件中对 bean 的描述) 如果说 XmlBeanFactory 是容器中的屌丝, ApplicationContext 应该算容器中的高帅富

ApplicationContext 是 Spring 提供的一个高级的 IOC 容器,它除了能够提供 IOC 容器的基本功能外, 还为用户提供了以下的附加服务。

从ApplicationContext 接口的实现,我们看出其特点
1. 支持信息源,可以实现国际化。(实现 MessageSource 接口)
2. 访问资源。 实现 ResourcePatternResolver 接口,后面章节会讲到
3. 支持应用事件。 实现 ApplicationEventPublisher 接口

(2)BeanDefinition

SpringIOC 容器管理了我们定义的各种 Bean 对象及其相互的关系, Bean 对象在 Spring 实现中是以 BeanDef inition 来描述的,其继承体系如下:

Bean的解析过程非常复杂,功能被分的很细,因为这里需要被扩展的地方很多,必须保证有足够的灵活性,以应对可能的变化。 Bean 的解析主要就是对 Spring 配置文件的解析。这个解析过程主要通过下图中的类完成:

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值