Spring 全家桶之 Spring Framework 5.3(一)

 2023-02-15
原文作者:RiemannHypothesis 原文地址:https://juejin.cn/post/7041546125458800654

一、Spring Framework Overview

Spring 官方文档 Version 5.3.13

Spring makes it easy to create Java enterprise applications.

Spring is open source.

Spring Framework

  • Spring简化了企业级应用的开发,通过Spring的核心IoC容器管理JavaBean,降低耦合
  • Spring是开源框架
  • Spring是非入侵式的,Spring开发的应用中对象不依赖Spring API
  • Spring DI依赖注入,是IOC控制反转的经典体现
  • Spring AOP 面向切面编程
  • Spring 组件化,由Spring IoC管理的JavaBean可以通过xml文件配置或者注解来实现

狭义的Spring即是指Spring Framework本身,即Core Container 核心容器,随着时间的推移,以Core Container为核心发展出了许多模块,广义的Spring即指众多Spring的模块,如Spring MVC, Spring Boot,Spring Data,Spring Cloud等,点击spring.io/projects 可以查看到Spring的众多模块

The term "Spring" means different things in different contexts. It can be used to refer to the Spring Framework project itself, which is where it all started. Over time, other Spring projects have been built on top of the Spring Framework. Most often, when people say "Spring", they mean the entire family of projects. This reference documentation focuses on the foundation: the Spring Framework itself.

Spring Framework 模块划分

202301012047323251.png

The IoC Container

Ioc 即 Inversion of Control,控制反转,由IoC 容器负责创建Bean代替通过new关键字创建

DI 即 Dependency Injection,依赖注入,IoC容器能知道哪个组件或类运行时需要另外一个组件或类,通过反射的方式注入

202301012047339932.png

创建 IoC Container

创建maven项目 ➡️ 添加maven依赖 ➡️ 创建配置文件 ➡️ 测试

    <properties>
        <spring-version>5.3.13</spring-version>
    </properties>
    
    
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

entity包中新增实体类Person

    public class Person {
        
        private String lastName;
        private Integer age;
        private String gender;
        private String email;
        // 省略getter/setter/toString方法
    }

resource目录下创建配置文件beans.xml

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
            https://www.springframework.org/schema/beans/spring-beans.xsd">
        将Person实体类注册到IoC容器中
        <bean id="person" class="com.citi.entity.Person">
        </bean>
    
    </beans>

3⃣️ 编写测试类

    public class ContainerTest {
    
        // 测试从容器中获取Bean
        @Test
        public void testStark(){
            ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");
            Person stark = (Person)context.getBean("stark");
            System.out.println(stark);
        }
    }

输出结果

202301012047346053.png

以上就完成了将Bean注册到容器,并从容器中获取Bean,整个过程没有使用new关键字来获取Bean,而是通过xml配置文件,将bean的属性全部写入xml文件中,在通过ApplicationContext接口的getBean()方法获取Bean

The org.springframework.context.ApplicationContext interface represents the Spring IoC container and is responsible for instantiating, configuring, and assembling the beans.

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.

ApplicationContext是IoC容器接口,负责实例化、配置和组装Bean,它有两个实现类ClassPathXmlApplicationContext和FileSystemXmlApplicationContext 这两个类实例化时需要传入配置文件,但是传入配置文件的方式不同

    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");
    ApplicationContext context1 = new FileSystemXmlApplicationContext("src/main/resources/beans.xml");

Bean 是什么时候实例化的?
在Person类中增加无参数构造方法,并添加输出语句

    public class Person {
    
        private String lastName;
        private Integer age;
        private String gender;
        private String email;
    
        //无参构造方法
        public Person() {
            System.out.println("无参构造方法被调用");
        }
        // 省略getter/setter/toString方法
    }

在ContainerTest类中增加输出语句

    public class ContainerTest {
    
        // 测试从容器中获取Bean
        @Test
        public void testStark(){
            ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");
            System.out.println("容器已创建完成");
            Person stark = (Person)context.getBean("stark");
            System.out.println(stark);
        }
    }

执行测试

202301012047350944.png

Bean是在容器初始化是创建的,不是在getBean时创建的

在ContainerTest方法中在获取一次Bean,验证两次获取的对象是否相等

    // 测试从容器中获取Bean
    @Test
    public void testStark(){
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");
        System.out.println("容器已创建完成");
        Person stark = (Person)context.getBean("stark");
        Person stark1 = (Person)context.getBean("stark");
    
        System.out.println(stark == stark1);
    }

输出结果

202301012047358665.png 结果为true,说明Person类只实例化了一次,就是在容器初始化的时候。

IoC 容器总结

  • ApplicationContext是IoC容器接口,有两个实现类ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,通过getBean()获取容器中的bean
  • 往容器中注册一个bean,bean的创建是由容器完成的,bean在容器初始化时就已经被创建完成
  • 同一个bean在容器中是单实例的
  • 容器中没有这个bean,会报错bean创建异常“No bean named 'xxx' is defined”
  • IoC容器在创建bean时,xml中property会利用类的setter设置bean的属性值