tlias智能学习辅助系统--原理篇-Bean管理

发布于:2025-08-08 ⋅ 阅读:(13) ⋅ 点赞:(0)

目录

1.Bean的作用域

1.1bean作用域

1.2注意:

1.3示例代码

1.4单例的bean(singleton)

1.5多例的bean(prototype)

1.6注意:

1.7面试题1:Spring容器的bean是单例的还是多例的?单例的bean是什么时候实例化的?

1.8面试题2:Spring容器的bean是线程安全的吗?

1.9延迟到第一次使用的时候,再来创建这个Bean

默认bean是单例的 - singleton

注释解释

2.第三方Bean

2.1示例代码

2.1.1启动类(不推荐)

2.1.2配置类(推荐)

2.2注意:

2.3什么时候使用@Component声明bean,什么时候使用@Bean注解?


1.Bean的作用域

1.1bean作用域

  • Spring支持五种作用域,后三种在web环境才生效:
作用域 说明
singleton 容器内同名称的bean只有一个实例(单例)(默认)
prototype 每次使用该bean时会创建新的实例(非单例/多例)
request 每个请求范围内会创建新的实例(web环境中,了解)
session 每个会话范围内会创建新的实例(web环境中,了解)
application 每个应用范围内会创建新的实例(web环境中,了解)

1.2注意:

默认singleton的bean,在容器启动时被创建,可以使用@Lazy注解来延迟初始化(延迟到第一次使用时)。

1.3示例代码

@Scope("prototype")
@RequestMapping("/depts")
@RestController
public class DeptController {
}

1.4单例的bean(singleton)

@Sl4j
@RestController
@Scope("singleton")
public class DeptController {
    @Autowired
    private DeptService deptService;

    @GetMapping("/depts")
    public Result list() {
        log.info("查询全部部门数据");
        List<Dept> deptList = deptService.findAll();
        return Result.success(deptList);
    }
}
  • 无状态的bean
  • 节约资源、提升性能

1.5多例的bean(prototype)

@Scope("prototype")
@Component
public class DataProcessor {
    private List<EmpModel> dataList = new ArrayList<EmpModel>(); // 暂存数据
    private Integer errCount = 0; // 错误数据统计

    @Autowired
    private EmpMapper empMapper;

    public void process(List<Emp> empList) {
        dataList = empList.stream().map(emp -> {
            // 数据处理
        }).toList();
    }

    public void handle() {
        // ...
    }
}
  • 有状态的bean

1.6注意:

实际开发当中,绝大部分的Bean是单例的,也就是说绝大部分Bean不需要配置scope属性。

1.7面试题1:Spring容器的bean是单例的还是多例的?单例的bean是什么时候实例化的?

  • 默认是单例的
  • 单例的bean,默认是项目启动时实例化的(通过@Lazy可以延迟初始化)

1.8面试题2:Spring容器的bean是线程安全的吗?

  • bean的线程安全取决于bean的状态及bean的作用域
    • 单例bean:如果是无状态的bean,内部不保存任何状态信息,则是线程安全的。
    • 单例bean:如果是有状态的bean,内部会保存状态信息,多个线程会同时操作该bean时,可能会出现数据不一致的问题,这样的bean则是线程不安全的。

1.9延迟到第一次使用的时候,再来创建这个Bean

默认bean是单例的 - singleton

  • 默认单例的bean是在项目启动时创建的,创建完毕后,会将该bean存入IOC容器。
//@Lazy //延迟初始化 ----> 延迟到第一次使用的时候,再来创建这个bean
@Scope("prototype") //非单例的 / 多例的
@RestController
public class DeptController {

    public DeptController() {
        System.out.println("创建DeptController对象...");
    }
}

注释解释

  • @Lazy:延迟初始化注解。如果加上这个注解,bean会在第一次被使用时才进行创建,而不是在项目启动时就创建。
  • @Scope("prototype"):指定bean的作用域为多例(prototype),即每次请求都会创建一个新的实例。

2.第三方Bean

  • 如果要管理的bean对象来自于第三方(不是自定义的),是无法用@Component及衍生注解声明bean的,就需要用到@Bean注解。
  • 若要管理的第三方bean对象,建议对这些bean进行集中分类配置,可以通过@Configuration注解声明一个配置类。

2.1示例代码

2.1.1启动类(不推荐)
@SpringBootApplication
public class SpringbootWebConfigApplication {
    @Bean // 将方法返回值交给IOC容器管理,成为IOC容器的bean对象
    public AliyunOSSOperator aliyunOSSOperator(AliyunOSSProperties ossProperties) {
        return new AliyunOSSOperator(ossProperties);
    }
}
2.1.2配置类(推荐)
@Configuration
public class OSSConfig {
    @Bean
    public AliyunOSSOperator aliyunOSSOperator(AliyunOSSProperties ossProperties) {
        return new AliyunOSSOperator(ossProperties);
    }
}

2.2注意:

  • 如果第三方bean需要依赖其它bean对象,直接在bean定义方法中设置形参即可,容器会根据类型自动装配。
  • 通过@Bean注解的name或value属性可以声明bean的名称,如果不指定,默认bean的名称就是方法名。

2.3什么时候使用@Component声明bean,什么时候使用@Bean注解?

  • 一般如果是项目中自定义的类,使用@Component及其衍生注解(如@Service、@Repository、@Controller等)。
  • 如果是引入第三方依赖中的类,使用@Bean注解。

网站公告

今日签到

点亮在社区的每一天
去签到