Bean管理

简单介绍了SpringBoot中bean的作用域及其使用场景,以及第三方bean的管理

Bean管理

Bean的作用域

Spring支持五种作用域,后三种在web环境才生效:

作用域 说明
singleton 容器内同名称的bean只有一个实例(单例)(默认)
prototype 每次使用该bean时会创建新的实例(非单例/多例)
request 每个请求范围内会创建新的实例(web环境中)
session 每个会话范围内会创建新的实例(web环境中)
application 每个应用范围内会创建新的实例(web环境中)
 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
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;

/**
 * 默认bean是单例的,多次获取是同一个对象
 * 默认的单例bean是在项目启动时创建的,创建完毕后存入Spring容器中
 * 可以在bean的类名上加上@Lazy注解来延迟到第一次使用时再创建bean对象
 */
@SpringBootTest
class SpringbootWebTests {
    @Autowired
    private ApplicationContext applicationContext; // Spring容器

    @Test
    public void testScope() {
        for (int i = 0; i < 3; i++) {
            Object bean = applicationContext.getBean("deptController");
            // 验证是否为同一个对象
            System.out.println(bean);
            /**
             * 输出结果:
             * com.itheima.controller.DeptController@4e4d0a0b
             * com.itheima.controller.DeptController@4e4d0a0b
             * com.itheima.controller.DeptController@4e4d0a0b
             */
        }
    }
}


// 下方为bean
@Lazy // 延迟到第一次使用时再创建bean对象
@RestController
public class DeptController {
    ...
}

修改bean的作用域为prototype,验证是否每次都不同:

 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
@SpringBootTest
class SpringbootWebTests {
    @Autowired
    private ApplicationContext applicationContext; // Spring容器

    @Test
    public void testScope() {
        for (int i = 0; i < 3; i++) {
            Object bean = applicationContext.getBean("deptController");
            // 验证是否为同一个对象
            System.out.println(bean);
            /**
             * 输出结果:
             * com.itheima.controller.DeptController@60652518
             * com.itheima.controller.DeptController@438aaa9f
             * com.itheima.controller.DeptController@3f06ebe0
             */
        }
    }
}

// 下方为bean
@Scope("prototype") // 修改bean的作用域为多例
@RestController
public class DeptController {
    ...
}

应用场景

  • 单例的bean(singleton)

如果是无状态的bean,就可以设置为单例

无状态的bean:在该对象中不保存数据

image-20250923214921769
  • 多例的bean(prototype)

如果是有状态的bean,就可以设置为多例

有状态的bean:在该对象中会保存数据

image-20250923215218916

在实际开发当中,绝大多数的Bean是单例的,不需要配置scope属性

第三方Bean

如果需要管理的bean对象来自于第三方,一般为只读的,无法编辑,也就无法使用@Component注解声明bean,此时可以使用@Bean注解

一种方法是在启动类当中进行管理,不过不推荐这种方式

image-20250923220811419

还有一种推荐的方式就是用@Configuration专门声明一个配置类,进行集中管理

image-20250923222023056

第三方bean需要依赖其他bean时,将其他bean定义在方法形参中即可,容器会根据类型自动装配

若第三方bean没有需要依赖的bean,形参部分空着即可

通过@Bean注解的name或value属性可以声明bean的名称,如果不指定,默认bean的名称就是方法名

本站于2025年3月26日建立
使用 Hugo 构建
主题 StackJimmy 设计