ZetCode

Spring Boot @Bean

上次修改时间:2023 年 7 月 23 日

在本文中,我们使用 @Bean 注解在 Spring Boot 框架中创建一个简单的 Bean。

Spring 是一个流行的 Java 应用框架,而 Spring Boot 是 Spring 的一个演进,它有助于以最小的努力创建独立的、生产级的基于 Spring 的应用程序。

Spring @Bean 注解

Spring @Bean 注解声明一个方法生成一个 Bean,由 Spring 容器管理。 这是一个方法级别的注解。 在 Java 配置 (@Configuration) 期间,该方法被执行,其返回值作为 Bean 注册在 BeanFactory 中。

Spring Boot @Bean 示例

核心 Spring 容器创建和管理 Bean。 在下面的应用程序中,我们展示了如何使用 @Bean 注解创建 Spring Bean。 应用程序是一个命令行 Spring Boot 应用程序。

build.gradle
...
src
├───main
│   ├───java
│   │   └───com
│   │       └───zetcode
│   │               Application.java
│   │               AppName.java
│   └───resources
│           application.properties
│           logback.xml
└───test
    ├── java
    └── resources

这是 Spring Boot 应用程序的项目结构。

build.gradle
plugins {
    id 'org.springframework.boot' version '3.1.1'
    id 'io.spring.dependency-management' version '1.1.0'
    id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
}

这是 Gradle 构建文件。spring-boot-starter 是核心启动器,包括自动配置支持、日志记录和 YAML。应用程序被打包成一个 JAR 文件。

com/zetcode/AppName.java
package com.zetcode;

interface AppName {

    String getName();
}

我们有一个简单的接口,它定义了一个契约。 它用于创建一个匿名类,该类返回应用程序名称。

resources/application.properties
spring.main.banner-mode=off
spring.main.log-startup-info=false
app.name=SpringBootBean

application.properties 文件包含应用程序配置设置。 有一些内置的应用程序属性,我们可以创建自定义属性。 spring.main.banner-mode 属性是 Spring 内置属性; 我们关闭 Spring 的横幅。 使用 spring.main.log-startup-info 属性,我们可以关闭启动日志记录信息。 app.name 是我们的自定义属性,它包含应用程序名称。

resources/logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml" />
    <logger name="org.springframework" level="ERROR"/>
    <logger name="com.zetcode" level="INFO"/>
</configuration>

logback.xml 文件中,我们配置应用程序日志记录。 我们将日志记录级别设置为 ERROR。 这样我们的输出就不会被不必要的信息所干扰。 spring-boot-starter 依赖项为日志记录启用了 logback。

com/zetcode/Application.java
package com.zetcode;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;

@SpringBootApplication
public class Application implements CommandLineRunner {

    private static final Logger logger = LoggerFactory.getLogger(Application.class);

    private final AppName appName;

    @Lazy
    public Application(AppName appName) {
        this.appName = appName;
    }

    @Bean
    public AppName getAppName(@Value("${app.name}") String appName) {

        return () -> appName;
    }

    @Override
    public void run(String... args) throws Exception {

        logger.info("Application name: {}", appName.getName());
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Application 中,我们创建一个 Bean,调用它的方法并设置 Spring Boot 应用程序。 CommandLineRunner 接口表示一个 Bean 应该在它包含在 SpringApplication 中时运行。 它可以用于在 Spring Boot 中创建命令行应用程序。

@SpringBootApplication
public class Application implements CommandLineRunner {

@SpringBootApplication 注解启用自动配置和组件扫描。

@Lazy
public Application(AppName appName) {
    this.appName = appName;
}

Bean 正在被注入; 我们使用 @Lazy 注解来避免循环 Bean 引用。

@Bean
public AppName getAppName(@Value("${app.name}") String appName) {

    return () -> appName;
}

在这里,我们创建 AppName Bean; 该 Bean 由 Spring 容器管理。 虽然 @Component 注解用于修饰由 Spring 扫描自动检测的类,但 @Bean 注解用于显式声明 Bean 创建。

@Value 注解用于将 app.name 属性的值设置为 appName 参数。

logger.info("Application name: {}", appName.getName());

我们调用 Bean 的 getName 方法。

$ ./gradlew bootRun 

> Task :bootRun
2023-07-23T16:49:02.009+02:00  INFO ... : Application name: SpringBootBean

我们使用 ./gradlew bootRun 运行应用程序。

在本文中,我们使用 @Bean 注解创建了一个 Spring Bean。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。 迄今为止,我撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出 所有 Spring Boot 教程