# Spring教程 - 2 HelloWorld

版本要求:

  • Spring 6
  • JDK 17
  • Maven 3.6+

开发工具 IntelliJ IDEA,没什么好说的。

# 2.1 创建HelloWorld

在以前编写代码的时候,我们都是通过 new 来创建 Java 对象,而现在使用 Spring 就是要实现让 Spring 帮我们创建和管理对象。

所以这里实现的是Hello World,就是不使用 new,而是让 Spring 帮我们创建对象。

# 1 创建项目

创建一个 Maven 项目,没什么好说的,轻车熟路。

# 2 集成Spring

在项目的 pom.xml 中添加 Spring 的依赖。

<?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.foooor</groupId>
    <artifactId>hello-spring</artifactId>
    <version>1.0-SNAPSHOT</version>

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


    <dependencies>
        <!-- 引入spring核心依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.2.9</version>
        </dependency>

        <!-- 引入junit5依赖 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.13.4</version>
        </dependency>

    </dependencies>

</project>
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
  • 在上面的代码中添加了 Spring 的核心依赖,以及 junit 测试相关的依赖。

添加完成,右键 pom.xml 文件,Maven -> Reload project ,下载一下依赖。

# 3 创建Java类

这里创建一个 UserService.java 类,我们要实现的就是让 Spring 创建这个类的对象。

创建包,并在包下创建类,如下:

添加一个简单的方法:

package com.foooor.hellospring.service;

public class UserService {

    /**
     * 获取用户
     */
    public void getUser() {
        System.out.println("获取用户信息");
    }

}
1
2
3
4
5
6
7
8
9
10
11
12

# 4 配置Spring文件

首先在项目的 resources 目录下创建一个 xml 文件,这里可以叫 bean.xml ,一般都叫这个名字,你也可以改。

在创建的时候,可以在 resources 目录上 右键 -> New -> XML Configuration File -> Spring Config 来创建 Spring 配置文件。

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


    <!-- 配置user对象的创建,需要指定id和类的全路径 -->
    <bean id="userService" class="com.foooor.hellospring.UserService">
    </bean>
  
</beans>
1
2
3
4
5
6
7
8
9
10
11
  • 在配置文件中主要指定类的全路径,这样可以通过配置找到对应的类。并给类指定一个 id,需要全局唯一,一般都是将类名改成首字母小写

# 5 测试

创建一个测试类,在测试类中编写测试代码。

首先加载 xml 配置文件,获取到 ApplicationContext ,然后通过 ApplicationContext对象获取 Java 对象。

package com.foooor.hellospring;

import com.foooor.hellospring.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserTest {

    @Test
    public void testUserService() {
        // 1. 加载spring的配置文件,在类路径下加载,类路径指的是src/main/resources
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        // 2. 获取配置创建的对象
        UserService userService = (UserService) context.getBean("userService");
        // 3. 调用对象的方法
        userService.getUser();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  • 可以看到,我们并没有使用 new 来创建对象,但是可以获取到对象,并执行其中的方法。

这里你可能想骂娘,这么复杂,我一个 new 多简单。

这里只是HelloWorld程序,只有一个类,没有体现 Spring 的威力,莫急,慢慢来。

# 2.2 HelloWorld解析

我们先简单介绍一下,上面的实现为什么能够获取到类对象。

原理其实很简单,就是通过反射来完成的,主要是下面几个步骤:

  1. 在启动的时候,Spring 加载 bean.xml,并使用解析器读取其中的 <bean> 标签。

  2. 每个 <bean> 标签会被转换为一个 BeanDefinition 对象,代表该 Bean 的定义信息(包括类名、作用域、依赖等)。

  3. Spring 会将这些 BeanDefinition 注册到一个 Map<String, BeanDefinition> 结构中,其中 key 是 <bean> 指定的 id 或 name,value 是 BeanDefinition

  4. 在初始化阶段,Spring 根据 BeanDefinition 使用反射实例化 Bean,并执行初始化等操作。

  5. 实例化后的 Bean(如果是单例的话)会被存入一个单例池中:Map<String, Object>,用于后续的 context.getBean(id) 调用。

  6. 然后就可以通过 context.getBean(id) 来获取对象,并调用方法了。

简单的说就是通过 XML 解析出类的路径,通过反射创建对象放到一个 Map 中,然后可以通过 key 来获取。

# 2.3 添加日志配置

在上面运行的时候,除了打印我们自己的日志,没有其他任何日志输出。其实 Spring 是输出了很多日志,但是因为没有引入日志框架,所以没有打印。

下面我们就在项目中引入 logback 的依赖,这个也是 Spring 官方推荐的日志实现框架。日志框架使用的门面模式,需要使用一个日志接口框架和一个日志实现框架,所以这里使用 SLF4J + Logback,当然你也可以使用 SLF4J + Log4j2

# 1 引入日志依赖

在项目中引入依赖如下:

<!-- 引入logback依赖,日志框架实现 -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.5.18</version>
</dependency>

<!-- 引入slf4j依赖,日志框架接口门面 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>2.0.17</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13

# 2 配置日志文件

在项目的 resources 目录下,创建 logback.xml 文件,对日志进行配置,可以配置输出到控制台和文件。

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <!-- 定义日志文件存放路径 -->
    <property name="LOG_PATH" value="./logs" />
    <!-- 定义日志文件路径 -->
    <property name="LOG_FILE" value="${LOG_PATH}/app.log" />

    <!-- 定义控制台输出 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 定义文件输出 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_FILE}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 按天生成新日志文件 -->
            <fileNamePattern>${LOG_PATH}/app.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 保留 30 天的日志 -->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 还可以单独指定某些包下的日志级别 -->
    <logger name="com.foooor.hellospring" level="DEBUG" />

    <!-- root 日志级别 -->
    <root level="DEBUG">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
    </root>

</configuration>
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
  • 上面配置了输出到控制台和文件中。

日志文件不用纠结如何配置,能看懂修改就行。

# 3 使用日志框架

此时重新运行上面 Hello World 的测试方法,就会打印 Spring 相关的日志了。

如下:


我们也可以在我们的代码中使用 logback 来打印日志。

举个栗子:

package com.foooor.hellospring.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UserService {

    // 创建日志对象
    private static final Logger logger = LoggerFactory.getLogger(UserService.class);

    /**
     * 获取用户
     */
    public void getUser() {
        logger.info("获取用户信息");

        logger.trace("这是 trace 级别日志");
        logger.debug("这是 debug 级别日志");
        logger.info("这是 info 级别日志");
        logger.warn("这是 warn 级别日志");
        logger.error("这是 error 级别日志");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  • 注意:引入的是 slf4j 相关的包

运行测试方法,执行结果如下:

日志是分等级的,我们在 logback.xml 配置的日志等级是 DEBUG,所以比 DEBUG 等级低的日志,就不会显示了。trace 是比 debug 等级低的,所以没有显示出来。

日志等级:error > warn > info > debug > trace