Administrator
发布于 2025-11-25 / 3 阅读
0

springboot bean

Springboot Bean是什么

Bean 是一个由 Spring IoC(Inversion of Control,控制反转)容器 管理的对象。它是 Spring 应用的核心构建块,几乎所有的组件(如服务、控制器、仓库等)都会被定义为 Bean,以便 Spring 容器能够统一创建、配置、管理和销毁它们。

什么是loc

传统开发中,对象的创建和依赖管理由开发者手动控制(例如 new UserService()userService.setDao(new UserDao()))。

而 Spring 的 IoC 容器会反转这种控制权:开发者只需声明对象的 “需求”(如需要一个 UserService),容器会自动负责对象的创建、依赖注入(DI)、生命周期管理(初始化、销毁)等,开发者直接使用容器提供的对象即可。

Bean 的本质

  • Bean 本质上是一个普通的 Java 对象(POJO),但它的创建、配置和生命周期由 Spring 容器掌控,而非开发者手动管理。
  • 容器通过读取配置(注解或 XML),识别哪些类需要被实例化为 Bean,然后将这些 Bean 存入一个 “容器”(可以理解为一个 Bean 仓库),后续需要时直接从容器中获取,无需重复创建。

如何创建 Bean?

Spring Boot 推荐使用 注解驱动 的方式创建 Bean,常用注解如下:

注解 作用 适用场景
@Component 通用注解,标记一个类为 Spring Bean 不确定具体层级的组件(如工具类)
@Service 专门标记 “服务层” 组件(业务逻辑) Service 层(如 UserService
@Repository 专门标记 “数据访问层” 组件(DAO) Repository 层(如 UserDao
@Controller 专门标记 “控制层” 组件(接收请求) Controller 层(如 UserController
@RestController 组合 @Controller@ResponseBody RESTful 接口的 Controller
@Configuration + @Bean 手动声明 Bean(适用于第三方类) 无法直接修改源码的类(如 DataSource

@Configuration + @Bean 创建 Bean

如果需要将第三方类(如数据库连接池 DataSource)注册为 Bean,可通过配置类手动声明:

// 标记为配置类,容器会扫描其中的 @Bean 注解
@Configuration
public class DataSourceConfig {

    // 声明一个名为“dataSource”的 Bean,容器会调用该方法创建实例
    @Bean
    public DataSource dataSource() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
        config.setUsername("root");
        config.setPassword("123456");
        return new HikariDataSource(config);
    }
}

Bean 的生命周期

Spring Bean 的生命周期可以概括为以下关键阶段(简化版):

  1. 实例化:容器根据 Bean 定义创建 Java 对象(调用构造方法)。
  2. 依赖注入:容器自动注入 Bean 的依赖(如 @Autowired 标记的属性)。
  3. 初始化
    • 调用 @PostConstruct 注解的方法(自定义初始化逻辑)。
    • 执行 InitializingBean#afterPropertiesSet() 方法(若实现该接口)。
  4. 就绪可用:Bean 进入容器的 “Bean 池”,等待被其他组件调用。
  5. 销毁
    • 容器关闭时,调用 @PreDestroy 注解的方法(自定义销毁逻辑)。
    • 执行 DisposableBean#destroy() 方法(若实现该接口)。

示例:生命周期回调

@Component
public class MyBean {

    // 构造方法(实例化阶段调用)
    public MyBean() {
        System.out.println("Bean 实例化:MyBean 构造方法执行");
    }

    // 依赖注入(实例化后调用)
    @Autowired
    private UserService userService;

    // 初始化方法(依赖注入后调用)
    @PostConstruct
    public void init() {
        System.out.println("Bean 初始化:@PostConstruct 执行");
    }

    // 销毁方法(容器关闭时调用)
    @PreDestroy
    public void destroy() {
        System.out.println("Bean 销毁:@PreDestroy 执行");
    }
}

Bean 的作用域

Bean 的 “作用域” 定义了 Bean 实例的创建方式和生命周期范围。Spring 支持多种作用域,常用的有:

作用域 说明 适用场景
singleton 默认,容器中仅存在一个 Bean 实例 无状态组件(如 Service、Dao)
prototype 每次请求 Bean 时,都创建一个新实例 有状态组件(如 Command、Request 级别的对象)
request 每个 HTTP 请求对应一个 Bean 实例 Web 应用中,与请求相关的组件
session 每个 HTTP Session 对应一个 Bean 实例 Web 应用中,与会话相关的组件
application 整个 Web 应用共享一个 Bean 实例 Web 应用的全局配置组件

示例:设置 Bean 作用域

// 将作用域设置为 prototype(每次请求创建新实例)
@Component
@Scope("prototype")
public class MyPrototypeBean {
    // ...
}

使用Bean来导入配置文件

当项目中存在多个数据源时,需要配置多个事务管理器,并通过 @TransactionaltransactionManager 属性指定使用哪个事务管理器。

示例配置:

  1. 配置多个数据源
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import com.zaxxer.hikari.HikariDataSource;

import javax.sql.DataSource;

@Configuration
public class DataSourceConfig {

    // 主数据源(默认使用)
    @Primary
    @Bean
    @ConfigurationProperties("spring.datasource.main")
    public DataSource mainDataSource() {
        return new HikariDataSource();
    }

    // 第二个数据源
    @Bean
    @ConfigurationProperties("spring.datasource.secondary")
    public DataSource secondaryDataSource() {
        return new HikariDataSource();
    }

    // 主事务管理器(默认使用)
    @Primary
    @Bean
    public PlatformTransactionManager mainTransactionManager() {
        return new DataSourceTransactionManager(mainDataSource());
    }

    // 第二个事务管理器
    @Bean
    public PlatformTransactionManager secondaryTransactionManager() {
        return new DataSourceTransactionManager(secondaryDataSource());
    }
}

配置文件(application.yml

spring:
  datasource:
    main:
      url: jdbc:mysql://localhost:3306/main_db
      username: root
      password: 123456
      driver-class-name: com.mysql.cj.jdbc.Driver
    secondary:
      url: jdbc:mysql://localhost:3306/secondary_db
      username: root
      password: 123456
      driver-class-name: com.mysql.cj.jdbc.Driver

使用多个事务管理器

@Service
public class MultiDataSourceService {

    private final MainUserRepository mainUserRepository;
    private final SecondaryUserRepository secondaryUserRepository;

    public MultiDataSourceService(MainUserRepository mainUserRepository, SecondaryUserRepository secondaryUserRepository) {
        this.mainUserRepository = mainUserRepository;
        this.secondaryUserRepository = secondaryUserRepository;
    }

    // 使用主事务管理器(默认)
    @Transactional(transactionManager = "mainTransactionManager")
    public void createMainUser(String username) {
        mainUserRepository.save(new MainUser(username));
    }

    // 使用第二个事务管理器
    @Transactional(transactionManager = "secondaryTransactionManager")
    public void createSecondaryUser(String username) {
        secondaryUserRepository.save(new SecondaryUser(username));
    }
}