0%

Spring入门程序

  • Spring的入门程序
    • 创建项目
    • 创建模块
    • Spring6 启用 Log4j2 日志框架

三、★Spring的入门程序

3.1 创建项目

  1. 打开 IDEA 创建 Empty Project:Spring-learning-code

    ![](../../../../../Running Noob/计算机/Typora笔记/笔记-git仓库/Java-SSM-notebook/img/Spring/spring入门程序1.png)

  2. 设置项目采用的编码 UTF-8

    ![](../../../../../Running Noob/计算机/Typora笔记/笔记-git仓库/Java-SSM-notebook/img/Spring/spring入门程序2.png)

  3. 设置项目 JDK 版本 17,编译器版本 17。

    ![](../../../../../Running Noob/计算机/Typora笔记/笔记-git仓库/Java-SSM-notebook/img/Spring/spring入门程序3.png)

  4. 设置项目的 Maven

    ![](../../../../../Running Noob/计算机/Typora笔记/笔记-git仓库/Java-SSM-notebook/img/Spring/spring入门程序4.png)

3.2 创建模块

  1. 在空的工程 Spring-learning-code 中创建第一个模块:spring6-001-first

    ![](../../../../../Running Noob/计算机/Typora笔记/笔记-git仓库/Java-SSM-notebook/img/Spring/spring入门程序5.png)

  2. 配置 spring6-001-first 模块的 pom.xml 文件,引入 spring contextjunit 依赖。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.f</groupId>
    <artifactId>spring6-001-first</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <repositories>
    <!--Spring里程碑版本的仓库-->
    <repository>
    <id>repository.spring.milestone</id>
    <name>Spring Milestone Repository</name>
    <url>https://repo.spring.io/milestone</url>
    </repository>
    </repositories>
    <dependencies>
    <!-- spring context依赖 -->
    <!--当你引入spring context依赖之后,表示将spring的基础依赖引入了-->
    <!--如果你想使用spring的jdbc,或者tx事务等,那么还需要再次添加依赖-->
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>6.0.8</version>
    </dependency>
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
    </dependency>
    </dependencies>

    <properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    </project>
  3. 定义普通 Java 类。

    • 在开发中,普通 Java 对象,称为 POJO(Plain Ordinary Java Object),或者称为 java bean(咖啡豆),也叫 domain(领域模型)。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    package com.f.spring6.bean;

    /**
    * 这是一个Bean,封装了用户的信息。
    * Spring可以帮我们创建User对象。
    *
    * @author fzy
    * @date 2024/1/14 13:37
    */
    public class User {
    private String name;
    private Integer age;

    public User() {
    }

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

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

    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;
    }
    }
  4. 编写 Spring 配置文件。

    • Spring 配置文件放在类根路径下,即 resources 目录下。
      • 该文件放在类的根路径下方便后期的移植。
      • 放在 resources 目录下,相当于放在类的根路径下。
    • Spring 的配置文件的命名任意。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <?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">
    <!--
    这就是spring的配置文件。
    IDEA工具为我们提供了这个文件的模板,一定要使用这个模板来创建。
    -->
    <!--这个文件名不一定叫做spring.xml,可以是其他名字-->
    <!--
    这个文件最好是放在类路径当中,方便后期的移植。
    放在resources根目录下,就相当于是放到了类的根路径下。
    -->
    <!--配置bean,这样spring才可以帮助我们管理这个对象-->
    <!--
    bean标签的两个重要属性:
    id:是这个bean的身份证号,不能重复,是唯一的标识。
    class:必须填写类的全限定类名。
    -->
    <bean id="userBean" class="com.f.spring6.bean.User"/>
    </beans>
  5. 编写测试类。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    package com.f.spring6.test;

    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    /**
    * @author fzy
    * @date 2024/1/14 13:59
    */
    public class FirstSpringTest {
    @Test
    public void testSpringFirstCode() {
    // 1.获取Spring容器对象
    // ApplicationContext 翻译为:应用上下文。其实就是Spring容器。
    // ApplicationContext 是一个接口。
    // ApplicationContext 接口下有很多实现类。其中有一个实现类叫做:ClassPathXmlApplicationContext
    // ClassPathXmlApplicationContext 是专门用于从类路径当中加载spring配置文件的一个Spring上下文对象。
    // 这行代码只要执行,就相当于启动了Spring容器,同时会解析spring.xml(Spring配置文件名)文件,
    // 并且实例化在Spring配置文件中配置的所有的bean对象,创建完成对象后会将其放到spring容器当中。
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    // 2.根据bean的id从Spring容器中获取这个对象
    Object userBean = applicationContext.getBean("userBean");
    System.out.println(userBean);
    }
    }

类根路径

  • 不管是 maven 还是普通的 java 模块,只要是 idea 文件夹中变成蓝色的部分,就可以理解为类路径的起始地点,之后的编译就是由蓝色文件夹开始算类路径的,自定义文件夹后用 idea 标记为 resources 后的文件夹也会被最终打包到类路径下。下图中的蓝色 java 目录和 resources 目录都相当于类的根路径,就是打包后,包的根路径。

    ![](../../../../../Running Noob/计算机/Typora笔记/笔记-git仓库/Java-SSM-notebook/img/Spring/类根路径.png)

    ![](../../../../../Running Noob/计算机/Typora笔记/笔记-git仓库/Java-SSM-notebook/img/Spring/类根路径2.png)

3.3 ★Spring入门程序分析

  1. bean 标签的 id 属性可以重复吗?

    1
    2
    3
    4
    5
    6
    7
    <?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">
    <bean id="userBean" class="cw.spring.study.pojo.User" />
    <bean id="userBean" class="cw.spring.study.pojo.User" />
    </beans>
    1
    2
    3
    org.springframework.beans.factory.parsing.BeanDefinitionParsingException: 
    Configuration problem: Bean name 'userBean' is already used in this <beans> element
    Offending resource: class path resource [spring.xml]
    • 通过测试得出:在 spring 的配置文件中 id 是不能重名的,因为 id 是每个 bean 的唯一表示
  2. 底层是怎么创建对象的,是通过反射机制调用无参数构造方法吗?

    • 默认情况下,Spring 会通过反射机制,调用类的无参数构造方法来实例化对象。spring 是通过调用类的无参数构造方法来创建对象的,所以要想让 spring 给你创建对象,必须保证无参数构造方法是存在的。
  3. spring 把创建好的对象存储到一个什么样的数据结构当中了呢?

    • Spring 把创建好的对象存储到一个 Map 集合当中。

      ![](../../../../../Running Noob/计算机/Typora笔记/笔记-git仓库/Java-SSM-notebook/img/Spring/spring存储对象.png)

  4. spring 配置文件的名字必须叫做 beans.xml 吗?

    • Spring 的配置文件的命名任意,因为 Spring 配置文件名字是我们负责提供的。
  5. 像这样的 beans.xml 文件可以有多个吗?

    • Spring 的配置文件可以有多个,在 ClassPathXmlApplicationContext 构造方法的参数中传递文件路径即可。且配置文件的文件名、文件路径都是任意的

      1
      2
      3
      4
      5
      6
      7
      8
      //ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring6.xml");
      //ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring6.xml", "beans.xml");
      ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring6.xml", "beans.xml", "xml/beans.xml");

      // 源码:
      public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {
      this(configLocations, true, (ApplicationContext)null);
      }
  6. 在配置文件中配置的类必须是自定义的吗,可以使用 JDK 中的类吗,例如:java.util.Date

    • 在 spring 配置文件中配置的 bean 可以是任意类,只要这个类不是抽象的,并且提供了无参数构造方法
  7. getBean() 方法调用时,如果指定的 id 不存在会怎样?

    • 会出现异常报错。

      1
      org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'xxx' available
  8. getBean() 方法返回的类型是 Object,如果访问子类的特有属性和方法时,还需要向下转型,有其它办法可以解决这个问题吗?

    • 如果不想强制类型转换,可以通过第二个参数来指定返回的 bean 的类型
    1
    2
    3
    4
    // Object userBean = applicationContext.getBean("userBean");
    // User userBean = (User) applicationContext.getBean("userBean");
    // 不想强制类型转换,可以使用以下代码(通过第二个参数来指定返回的bean的类型。)
    User userBean = applicationContext.getBean("userBean", User.class);
  9. ClassPathXmlApplicationContext 是从类路径中加载配置文件,如果没有在类路径当中,又应该如何加载配置文件呢?

    • 没有在类路径中的话,需要使用 FileSystemXmlApplicationContext 类进行加载配置文件。

      • 从指定的文件路径加载配置文件。
      1
      ApplicationContext applicationContext2 = new FileSystemXmlApplicationContext("d:/spring6.xml");

      这种方式较少用,一般都是将配置文件放到类路径当中,这样可移植性更强。

  10. ApplicationContext 的顶级父接口 BeanFactory

    • BeanFactory 翻译为 Bean 工厂,就是能够生产 Bean 对象的一个工厂对象。

    • BeanFactory 是 Spring 容器的顶级接口。ApplicationContextBeanFactory 的子接口。

    • Spring 的 IoC 容器底层实际上使用了 “工厂模式”。

      • Spring 底层的 IoC 容器是通过:XML 解析 + 工厂模式 + 反射机制 实现的。
  11. Spring 不是在调用 getBean() 方法的时候才创建对象,在执行 new ClassPathXmlApplicationContext("spring6.xml"); 加载配置文件的时候,就会实例化对象

3.4 Spring6 启用 Log4j2 日志框架

  • 从 Spring5 之后,Spring 框架支持集成的日志框架是 Log4j2

    启用日志框架有助于我们更好的跟踪程序,以及在程序出错时,我们可以更快的进行错误的查找与排除。

  1. pom.xml 文件中引入 Log4j2 的依赖。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    ...
    <dependencies>
    ...
    <!--log4j2的依赖-->
    <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.19.0</version>
    </dependency>
    <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j2-impl</artifactId>
    <version>2.19.0</version>
    </dependency>
    </dependencies>
    ...
  2. 提供 log4j2.xml 配置文件:

    • 在类根路径下提供 log4j2.xml 配置文件。
    • 配置文件的文件名固定为:log4j2.xml,且文件必须放到类根路径下。
      • 配置文件的文件名是固定的,位置也是固定的,必须在类的根目录及其子目录下。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <?xml version="1.0" encoding="UTF-8"?>

    <configuration>

    <loggers>
    <!--
    level指定日志级别,从低到高的优先级:
    ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF
    达到相应的级别才会输出日志信息
    级别越低输出的日志信息越多
    -->
    <!-- 日志输出级别为 DEBUG,该级别之下的日志不会输出 -->
    <root level="DEBUG">
    <appender-ref ref="spring6log"/>
    </root>
    </loggers>

    <appenders>
    <!--输出日志信息到控制台-->
    <console name="spring6log" target="SYSTEM_OUT">
    <!--控制日志输出的格式-->
    <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/>
    </console>
    </appenders>

    </configuration>
  3. 使用日志框架:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    @Test
    public void testLog4j2() {
    // 获取日志记录器对象(记录日志需要一个日志记录器)
    // 获取FirstSpringTest类的日志记录器对象,只要是FirstSpringTest类中的代码执行记录日志的话,就输出相关的日志信息。
    Logger logger = LoggerFactory.getLogger(com.f.spring6.test.FirstSpringTest.class);

    // 记录日志,记录不同的级别的日志
    // 输出日志时,根据配置文件中设置的输出日志级别进行输出
    logger.trace("我是一条查找追踪信息");
    logger.debug("我是一条调试信息");
    logger.info("我是一条消息");
    logger.error("我是一条错误信息");
    }
    1
    2
    3
    2024-01-14 15:05:39 191 [main] DEBUG com.f.spring6.test.FirstSpringTest - 我是一条调试信息
    2024-01-14 15:05:39 194 [main] INFO com.f.spring6.test.FirstSpringTest - 我是一条消息
    2024-01-14 15:05:39 194 [main] ERROR com.f.spring6.test.FirstSpringTest - 我是一条错误信息
    • 因为在 log4j2.xml 文件中,日志输出级别设置为 DEBUG,所以 TRACE 的信息并没有被输出。
---------------The End---------------