ZetCode

Spring Boot @Component

最后修改于 2023 年 7 月 16 日

Spring Boot @Component 教程展示了如何在 Spring 应用中使用 @Component 注解。在这个例子中,我们创建了一个 Spring Boot 控制台应用。

Spring 是一个流行的 Java/Kotlin 应用框架,而 Spring Boot 是 Spring 的一个演进版本,它有助于轻松创建独立的、生产级的基于 Spring 的应用。

@Component

@Component 是最通用的 Spring 注解。用 @Component 装饰的 Java 类在类路径扫描期间被发现,并在上下文中注册为 Spring Bean。@Service, @Repository@Controller@Component 的特化,用于更具体的情况。

@ComponentScan 确保用 @Component 装饰的类被找到并注册为 Spring Bean。 @ComponentScan@SpringBootApplication 自动包含。

@Bean 的作用与 @Component 类似。它不会被自动检测。用 @Bean 装饰的方法会产生一个 bean,在配置阶段由 Spring 容器管理。

Spring Boot @Component 示例

以下应用演示了 @Component 的用法。它使用该注解创建一个随机生成名称的 bean。

build.gradle 
...
src
├── main
│   ├── java
│   │   └── com
│   │       └── zetcode
│   │           ├── Application.java
│   │           ├── MyRunner.java
│   │           └── service
│   │               ├── NowService.java
│   │               └── RandomNameService.java
│   └── resources
└── test
    ├── java
    └── resources

这是项目结构。

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

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

java {
    sourceCompatibility = '17'
}

repositories {
    mavenCentral()
}

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

这是 Gradle 构建文件。 spring-boot-starter 是一个核心 starter,包括自动配置支持、日志记录和 YAML。

resources/application.properties
spring.main.banner-mode=off
logging.level.org.springframework=ERROR
logging.pattern.console=%d{dd-MM-yyyy HH:mm:ss} %magenta([%thread]) %highlight(%-5level) %logger.%M - %msg%n

application.properties 是 Spring Boot 中的主要配置文件。我们关闭 Spring banner,通过仅选择错误消息来减少 Spring 框架的日志记录量,并设置控制台日志记录模式。

com/zetcode/service/RandomNameService.java
package com.zetcode.service;

import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Random;

@Service
public class RandomNameService {

    private final List<String> names = List.of("Paul", "Peter", "Lucia", 
        "Martin", "Robert", "Svetlana");

    public String getName() {

        var rand = new Random();
        return names.get(rand.nextInt(names.size()));
    }
}

RandomNameService 是一个用 @Service 装饰的 Java 类,它是 @Component 的一个特例。它将在组件扫描过程中被检测到并注册为 Spring Bean。

com/zetcode/service/NowService.java
package com.zetcode.service;

import org.springframework.stereotype.Service;

import java.time.Instant;

@Service
public class NowService {

    public String now() {

        return Instant.now().toString();
    }
}

这是另一个服务类。

com/zetcode/MyRunner.java
package com.zetcode;

import com.zetcode.service.RandomNameService;
import com.zetcode.service.NowService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class MyRunner implements CommandLineRunner {

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

    private final RandomNameService randomNameService;
    private final NowService nowService;

    public MyRunner(RandomNameService randomNameService, NowService nowService) {
        this.randomNameService = randomNameService;
        this.nowService = nowService;
    }

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

            logger.info("Random name: {}", randomNameService.getName());
            logger.info("Now: {}", nowService.now());
    }
}

通过实现 CommandLineRunner 接口,MyRunner 类的 run 方法将在应用启动后执行。

@Component
public class MyRunner implements CommandLineRunner {

MyRunner@Component 装饰,因此它将被自动检测和注册。

private final RandomNameService randomNameService;
private final NowService nowService;

public MyRunner(RandomNameService randomNameService, NowService nowService) {
    this.randomNameService = randomNameService;
    this.nowService = nowService;
}

我们注入了两个服务 bean。

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

        logger.info("Random name: {}", randomNameService.getName());
        logger.info("Now: {}", nowService.now());
}

run 方法中,我们调用了服务方法。

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

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application  {

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

Application 是设置 Spring Boot 应用的入口点。 @SpringBootApplication 注解启用自动配置和组件扫描。它是 @Configuration, @EnableAutoConfiguration@ComponentScan 注解的便捷注解。

$ ./gradlew bootRun
...
2023-07-16T11:57:20.396+02:00  INFO 14480 --- [main] com.zetcode.MyRunner: Random name: Robert
2023-07-16T11:57:20.398+02:00  INFO 14480 --- [main] com.zetcode.MyRunner: Now: 2023-07-16T09:57:20.398118100Z

应用运行后,我们可以在控制台中看到日志消息。

在本教程中,我们展示了如何在 Spring 应用中使用 @Component 注解。

作者

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

列出 所有 Spring Boot 教程