[Spring]一文明白IOC容器和思想

✅作者简介:大家好,我是Philosophy7?让我们一起共同进步吧!
个人主页:Philosophy7的csdn博客
系列专栏: 数据结构与算法
哲学语录: 承认自己的无知,乃是开启智慧的大门
如果觉得博主的文章还不错的话,请点赞+收藏⭐️+留言支持一下博>主哦


文章目录

  • 一、Spring简介
    • 1.1、SpringFramework创始人
    • 1.2、Spring全家桶
    • 1.3、SpringFramework
      • 1) Feauture:
      • 2) SpringFramework五大模块
  • 二、IOC
    • 前言:
      • Container Overview
      • Bean Overview
    • 2.1、思想:
    • 2.2、IOC容器的实现
    • 2.3、基于XML管理Bean
      • `实操一:入门案例HelloWorld`
        • 1) 创建Maven项目
        • 2) 改pom.xml
        • 3) 创建HelloWorld类
        • 4) 创建配置文件
        • 5) 测试
        • 执行流程
      • `实操二: 获取Bean`
      • `实操三: 依赖注入setter方式`
        • 1) 创建实体类Person
        • 2) 配置Bean并实现属性赋值
        • 3) 测试
      • `实操四: 依赖注入构造器方式`
        • 1) 编写有参构造
        • 2)配置Bean
        • 3)测试
      • `实操五: 特殊值处理`
      • `实操六: 为引用类型赋值(级联赋值)`
        • 1) 创建身份证类IdCard
        • 2) 修改Person类
        • 3) 配置Bean
        • 4) 测试

一、Spring简介

[Spring | Home](https://spring.io/)官网地址,由于Spring是国外网站,可能访问速度会有点慢。

[Spring]一文明白IOC容器和思想_第1张图片

Spring使创建Java企业应用程序变得容易。它提供了在企业环境中使用Java语言所需的一切,支持Groovy和Kotlin作为JVM上的替代语言,并根据应用程序的需要灵活地创建多种体系结构。从Spring Framework 5.1开始,Spring需要JDK 8+ (Java SE 8+),并提供对JDK 11 LTS的开箱即用支持。Java SE 8 update 60被建议作为Java 8的最低补丁版本,但通常建议使用最新的补丁版本。

Spring 是最受欢迎的企业级 Java 应用程序开发框架,数以百万的来自世界各地的开发人员使用 Spring 框架来创建性能好、易于测试、可重用的代码。

Spring 框架是一个开源的 Java 平台,它最初是由 Rod Johnson 编写的,并且于 2003 年 6 月首 次在 Apache 2.0 许可下发布。 Spring 是轻量级的框架,其基础版本只有 2 MB 左右的大小。

Spring 框架的核心特性是可以用于开发任何 Java 应用程序,但是在 Java EE 平台上构建 web 应 用程序是需要扩展的。 Spring 框架的目标是使 J2EE 开发变得更容易使用,通过启用基于 POJO 编程模型来促进良好的编程实践。

1.1、SpringFramework创始人

Rod Johnson,Spring框架的创始人,同时也是SpringSource的联合创始人。Spring是面向切面编程(AOP)和控制反转(IoC)的容器框架。

[Spring]一文明白IOC容器和思想_第2张图片

1.2、Spring全家桶

[Spring | Projects](https://spring.io/projects)

在该链接可以看出Spring的生态包含哪些,在这我列举我们常用的Spring Framework、SpringBoot、SpringCloud、SpringSecurity、SpringAMQP等

1.3、SpringFramework

以Spring为基础框架,可以把Spring看作成地基,基本上所有的Spring项目都是以SpringFramework为基础的。

1) Feauture:

  • Core technologies: dependency injection, events, resources, i18n, validation, data binding, type conversion, SpEL, AOP.
  • Testing: mock objects, TestContext framework, Spring MVC Test, WebTestClient
  • Data Access: transactions, DAO support, JDBC, ORM, Marshalling XML.
  • Spring MVC and Spring WebFlux web frameworks.
  • Integration(集成): remoting, JMS, JCA, JMX, email, tasks, scheduling, cache.
  • Languages: Kotlin, Groovy, dynamic languages.

核心技术: 依赖注入(Dependency injection 简称DI)、事件、数据绑定、SPEL表达式、AOP面向切面等

测试: SpringMVC测试、WebTestClient等

数据访问: 事务、支持DAO、JDBC、ORM、XML

2) SpringFramework五大模块

功能模块 功能介绍
Core Container 核心容器,在 Spring 环境下使用任何功能都必须基于 IOC 容器。
AOP&AspectJs 面向切面编程
Testings 提供了对 junit 或 TestNG 测试框架的整合。
Data Access/Integration 提供了对数据访问/集成的功能。
Spring MVC 提供了面向Web应用程序的集成功能

二、IOC

Inversion of Control,反转控制。那么什么是控制反转呢,就是将对象的创建权改变了,创建对象的任务交给IOC容器进行管理。

//原始创建方式 --- 采用new的方式来创建对象
Object obj = new Object();

前言:

Container Overview

The org.springframework.context.ApplicationContext interface represents the Spring IoC container and is responsible for instantiating, configuring, and assembling the beans. The container gets its instructions on what objects to instantiate, configure, and assemble by reading configuration metadata. The configuration metadata is represented in XML, Java annotations, or Java code. It lets you express the objects that compose your application and the rich interdependencies between those objects.

Several implementations of the ApplicationContext interface are supplied with Spring. In stand-alone applications, it is common to create an instance of ClassPathXmlApplicationContext or FileSystemXmlApplicationContext. While XML has been the traditional format for defining configuration metadata, you can instruct the container to use Java annotations or code as the metadata format by providing a small amount of XML configuration to declaratively enable support for these additional metadata formats.

In most application scenarios, explicit user code is not required to instantiate one or more instances of a Spring IoC container. For example, in a web application scenario, a simple eight (or so) lines of boilerplate web descriptor XML in the web.xml file of the application typically suffices (see Convenient ApplicationContext Instantiation for Web Applications). If you use the Spring Tools for Eclipse (an Eclipse-powered development environment), you can easily create this boilerplate configuration with a few mouse clicks or keystrokes.

Bean Overview

A Spring IoC container manages one or more beans. These beans are created with the configuration metadata that you supply to the container (for example, in the form of XML definitions).

Within the container itself, these bean definitions are represented as BeanDefinition objects, which contain (among other information) the following metadata:

  • A package-qualified class name: typically, the actual implementation class of the bean being defined.
  • Bean behavioral configuration elements, which state how the bean should behave in the container (scope, lifecycle callbacks, and so forth).
  • References to other beans that are needed for the bean to do its work. These references are also called collaborators or dependencies.
  • Other configuration settings to set in the newly created object — for example, the size limit of the pool or the number of connections to use in a bean that manages a connection pool.

以上内容来源于官网,为避免翻译难免有失偏颇,可自行翻译

2.1、思想:

IOC容器的引入,让我们的开发变的快捷、方便、高效,且IOC容器能够解耦合降低类与类之间的依赖关系。

①获取资源的传统方式:

传统的方式是组件主动的从容器中获取所需要的资源,在这样的 模式下开发人员往往需要知道在具体容器中特定资源的获取方式,增加了学习成本,同时降低了开发效 率。

②反转控制方式获取资源:

只需要将资源放入到容器之中,容器如何创建对象开发人员不需要关心,只需要明白如何从容器中获取这个资源即可。

③DI

DI(Dependency Injection) 依赖注入

DI 是 IOC 的另一种表述方式:即组件以一些预先定义好的方式(例如:setter 方法)接受来自于容器 的资源注入。相对于IOC而言,这种表述更直接。

所以结论是:IOC 就是一种反转控制的思想, 而 DI 是对 IOC 的一种具体实现

2.2、IOC容器的实现

Spring 的 IOC 容器就是 IOC 思想的一个落地的产品实现。IOC 容器中管理的组件也叫做 bean。在创建 bean 之前,首先需要创建 IOC 容器。Spring 提供了 IOC 容器的两种实现方式:

  • BeanFactory
    • 这是 IOC 容器的基本实现,是 Spring 内部使用的接口。面向 Spring 本身,不提供给开发人员使用。
  • ApplicationContext
    • BeanFactory 的子接口,提供了更多高级特性。面向 Spring 的使用者,几乎所有场合都使用 ApplicationContext 而不是底层的 BeanFactory。

ApplicationContext的实现类

[Spring]一文明白IOC容器和思想_第3张图片

类型名 简介
ClassPathXmlApplicationContext 通过读取类路径下的 XML 格式的配置文件创建 IOC 容器对象
FileSystemXmlApplicationContext 通过文件系统路径读取 XML 格式的配置文件创建 IOC 容 器对象
ConfigurableApplicationContext ApplicationContext 的子接口,包含一些扩展方法 refresh() 和 close() ,让 ApplicationContext 具有启动、 关闭和刷新上下文的能力。
WebApplicationContext 专门为 Web 应用准备,基于 Web 环境创建 IOC 容器对 象,并将对象引入存入 ServletContext 域中。

2.3、基于XML管理Bean

实操一:入门案例HelloWorld

1) 创建Maven项目

maven项目管理工具,来对项目进行管理

2) 改pom.xml

 <dependencies>
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-contextartifactId>
            <version>5.3.1version>
        dependency>
        
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.12version>
            <scope>testscope>
        dependency>
dependencies>

3) 创建HelloWorld类

public class HelloWorld {
    //编写方法
    public void sayHello(){
        System.out.println("Hello World");
    }
}

4) 创建配置文件

resource包下创建applicationContext.xml,通常都是以该文件名命名

[Spring]一文明白IOC容器和思想_第4张图片



<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">


    <bean id="helloWorld" class="com.philosophy.spring.bean.HelloWorld">bean>
beans>

5) 测试

@Test
public void test() {
     //通过xml文件的方式来管理Bean
     ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

     //2.获取Bean对象 getBean可传递Bean的ID 或 对应的Class类对象
     HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld");

     //3.调用方法
     helloWorld.sayHello();
}

执行流程

[Spring]一文明白IOC容器和思想_第5张图片

1.创建组件类 --> 2.将组件配置到配置文件中 3.创建IOC容器对象 读取配置文件中的Bean 4.获取IOC中容器的对象 5.完成特定功能

实操二: 获取Bean

①方式一: 根据Bean的ID获取:

由于 id 属性指定了 bean 的唯一标识,所以根据 bean 标签的 id 属性可以精确获取到一个组件对象。 上个实验中我们使用的就是这种方式

//根据Bean的唯一标识来获取
HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld");

②方式二: 根据类型获取

HelloWorld helloWorld = context.getBean(HelloWorld.class);

③方式三:根据ID和类型获取

HelloWorld bean = context.getBean("helloWorld", HelloWorld.class);

④注意:

当根据类型获取Bean时,要求IOC容器中指定的类型Bean只能有一个

当IOC容器中一共配置了两个相同的类型时

<bean id="helloWorld" class="com.philosophy.spring.bean.HelloWorld">bean>
<bean id="helloWorldTwo" class="com.philosophy.spring.bean.HelloWorld">bean>

根据类型时获取Bean就会抛出异常

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.philosophy.spring.bean.HelloWorld' available: expected single matching bean but found 2: helloWorld,helloWorldTwo

实操三: 依赖注入setter方式

1) 创建实体类Person

package com.philosophy.spring.bean;

public class Person {
    private Integer id; //ID
    private String name; //name名称
    private Integer age; //名称

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

2) 配置Bean并实现属性赋值

<bean id="person" class="com.philosophy.spring.bean.Person">
        
        
        
        <property name="id" value="1001"/>
        <property name="name" value="张三"/>
        <property name="age" value="20"/>
bean>

3) 测试

@Test
public void testPerson() {
    //1.创建IOC容器
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    //2.获取对象
    Person person = context.getBean(Person.class);

    System.out.println(person);
}

实操四: 依赖注入构造器方式

1) 编写有参构造

public Person(Integer id,String name,Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
}

2)配置Bean

<bean id="personTwo" class="com.philosophy.spring.bean.Person">
    
    <constructor-arg value="1002"/>
    <constructor-arg value="李四"/>
    <constructor-arg value="33"/>
bean>

3)测试

@Test
public void testPerson02() {
    //1.创建IOC容器
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    //2.获取对象
    Person person = (Person) context.getBean("personTwo");

    System.out.println(person);
}

实操五: 特殊值处理

①、什么是字面量?

//声明一个变量
int a = 10;

声明一个变量a,初始化值为10,此时a代表的是一个变量名称,当我们引用a时获取的是其值10

若a是一个带引号的'a',那么它就不是一个变量,它就是这个字母的本身,这就是字面量


<property name="name" value="张三"/>

②、null值


<property name="name">
	<null />
property>

<property name="name" value="null">property> 

③CDATA


    
    
    
    
    

实操六: 为引用类型赋值(级联赋值)

1) 创建身份证类IdCard

package com.philosophy.spring.bean;

/**
 * 身份证类
 */
public class IdCard {
    private String id; //身份证号

    public IdCard(String id) {
        this.id = id;
    }

    public IdCard() {
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

2) 修改Person类

添加以下代码:

private IdCard idCard; //身份证号

public IdCard getIdCard() {
        return idCard;
}

public void setIdCard(IdCard idCard) {
        this.idCard = idCard;
}

@Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", idCard=" + idCard +
                '}';
    }

3) 配置Bean

 	<bean id="idCard" class="com.philosophy.spring.bean.IdCard">
        <property name="id" value="10086"/>
    bean>

    <bean id="personThree" class="com.philosophy.spring.bean.Person">
        <property name="id" value="1003"/>
        <property name="name" value="鸡哥"/>
        <property name="age" value="23"/>
        
        <property name="idCard" ref="idCard"/>
    bean>

4) 测试

@Test
    public void testPersonAndIdCard() {
        //1.创建IOC容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        //2.获取对象
        Person person = (Person) context.getBean("personThree");

        System.out.println(person);
    }

你可能感兴趣的:(SSM,1024程序员节,后端,spring,java-ee)