Spring学习(四)IOC详解

一、简介

  概念:控制反转是一种通过描述(在 Java 中可以是 XML 或者注解)并通过第三方(Spring)去产生或获取特定对象的方式。(被动创建)

  优势:

  ① 降低对象之间的耦合

  ② 我们不需要理解一个类的具体实现,只需要知道它有什么用就好了(直接向 IoC 容器拿)

  小结:主动创建的模式中,责任归于开发者,而在被动的模式下,责任归于 IoC 容器,基于这样的被动形式,我们就说对象被控制反转了。(也可以说是反转了控制)

二、IOC容器

  Spring 会提供IoC 容器来管理和容纳我们所开发的各种各样的 Bean,并且我们可以从中获取各种发布在 Spring IoC 容器里的 Bean,并且通过描述可以得到它。

 三、容器设计

  主要基于BeanFactoryApplicationContext 两个接口。

  BeanFactory 是 Spring IoC 容器所定义的最底层接口,而 ApplicationContext 是其最高级接口之一,并对 BeanFactory 功能做了许多的扩展,所以在绝大部分的工作场景下,都会使用 ApplicationContext 作为 Spring IoC 容器

  ApplicationContext的常用扩展类:

ClassPathXmlApplicationContext:从类路径下加载配置文件

FileSystemXmlApplication:从硬盘的绝对路径下加载配置文件

BeanFactory

 常用方法

【getBean】对应了多个方法来获取配置给 Spring IoC 容器的 Bean。

按照类型拿 bean:

bean = (Bean) factory.getBean(Bean.class);

PS:要求在 Spring 中只配置了一个这种类型的实例,否则报错。(如果有多个那 Spring 就懵了,不知道该获取哪一个)

按照 bean 的名字拿 bean:

bean = (Bean) factory.getBean("beanName");

PS:这种方法不太安全,IDE 不会检查其安全性(关联性)

按照名字和类型拿 bean:(推荐)

bean = (Bean) factory.getBean("beanName", Bean.class);

【isSingleton】用于判断是否单例,如果判断为真,其意思是该 Bean 在容器中是作为一个唯一单例存在的。

【isPrototype】则相反,如果判断为真,意思是当你从容器中获取 Bean,容器就为你生成一个新的实例。

PS:在默认情况下,【isSingleton】为 ture,而【isPrototype】为 false

【getAliases】方法是获取别名的方法

ApplicationContext

1、先在【src】目录下创建一个 【bean.xml】 文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 通过 xml 方式装配 bean -->
    <bean name="source" class="pojo.Source">
        <property name="fruit" value="橙子"/>
        <property name="sugar" value="多糖"/>
        <property name="size" value="超大杯"/>
    </bean>
</beans>

PS:这里定义了一个 bean ,这样 Spring IoC 容器在初始化的时候就能找到它们,然后使用 ClassPathXmlApplicationContext 容器就可以将其初始化

2、使用 ClassPathXmlApplicationContext 容器将其初始化:

ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
Source source = (Source) context.getBean("source", Source.class);

System.out.println(source.getFruit());
System.out.println(source.getSugar());
System.out.println(source.getSize());

四、ApplicationContext的常见实现类

ClassPathXmlApplicationCntext

读取classpath中的资源

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

FileSystemXmlApplicationContext

读取指定路径的资源

ApplicationContext ac = new FileSystemXmlApplicationContext("c:/applicationContext.xml");

XmlWebApplicationContext

需要在Web的环境下才可以运行

XmlWebApplicationContext ac = new XmlWebApplicationContext(); // 这时并没有初始化容器
ac.setServletContext(servletContext); // 需要指定ServletContext对象
ac.setConfigLocation("/WEB-INF/applicationContext.xml"); // 指定配置文件路径,开头的斜线表示Web应用的根目录
ac.refresh(); // 初始化容器

五、IOC初始化、注入的实现原理

Bean的定义

1、资源定位

Spring IoC 容器先根据开发者的配置,进行资源的定位,在 Spring 的开发中,通过 XML 或者注解都是十分常见的方式,定位的内容是由开发者提供的。

2、获取Bean

这个时候只是将定位到的资源信息,保存到 Bean 定义(BeanDefinition)中,此时并不会创建 Bean 的实例。

3、注册Bean到IOC容器中

将定义好的Bean的信息发布到 Spring IoC 容器中

PS:做完了以上 3 步,Bean 就在 Spring IoC 容器中被定义了,但是没有被初始化,更没有完成依赖注入,此时它还不能完全使用。

Bean的初始化和注入

Spring IoC 默认会自动初始化 Bean

Spring Bean 还有一个配置选项——【lazy-init】,其含义就是是否初始化 Spring Bean

如果将其设置为 true,那么只有当我们使用 Spring IoC 容器的 getBean 方法获取它时,它才会进行 Bean 的初始化,完成依赖注入。

 

原文地址:https://www.cnblogs.com/riches/p/11510981.html