diff --git a/李柏霖学习笔记/4.3.md b/李柏霖学习笔记/4.3.md new file mode 100644 index 0000000..d7a1760 --- /dev/null +++ b/李柏霖学习笔记/4.3.md @@ -0,0 +1,43 @@ +# 复习 + + + +依赖注入方面,`@Autowired` 是用得最多的,可以标注在字段、setter 方法或者构造方法上。`@Qualifier` 在有多个同类型 Bean 的时候用来指定具体注入哪一个。`@Resource` 和 `@Autowired` 功能差不多,不过它是按名称注入的。 + + + +配置相关的注解也很常用。`@Configuration` 标识配置类,`@Bean` 用来定义 Bean,`@Value` 用来注入配置文件中的属性值。我们项目里的数据库连接信息、Redis 配置这些都是用 `@Value` 来注入的。`@PropertySource` 用来指定配置文件的位置。 + + + + + +单例模式也是 Spring 的默认行为。默认情况下,Spring 容器中的 Bean 都是单例的,整个应用中只会有一个实例。这样可以节省内存,提高性能。可以通过 `@Scope` 注解来改变 Bean 的作用域,比如设置为 prototype 就是每次获取都创建新实例。 + +![二哥的 Java 进阶之路:@Scope注解](https://cdn.paicoding.com/stutymore/spring-20250618113356.png) + +#### Spring如何实现单例模式 + +传统的单例模式是在类的内部控制只能创建一个实例,比如用 private 构造方法加 `static getInstance()` 这种方式。但是 Spring 的单例是容器级别的,同一个 Bean 在整个 Spring 容器中只会有一个实例。 + +具体的实现机制是这样的:Spring 在启动的时候会把所有的 Bean 定义信息加载进来,然后在 DefaultSingletonBeanRegistry 这个类里面维护了一个叫 singletonObjects 的 ConcurrentHashMap,这个 Map 就是用来存储单例 Bean 的。key 是 Bean 的名称,value 就是 Bean 的实例对象。 + +当我们第一次获取某个 Bean 的时候,Spring 会先检查 singletonObjects 这个 Map 里面有没有这个 Bean,如果没有就会创建一个新的实例,然后放到 Map 里面。后面再获取同一个 Bean 的时候,直接从 Map 里面取就行了,这样就保证了单例。 + +还有一个细节就是 Spring 为了解决循环依赖的问题,还用了三级缓存。除了 singletonObjects 这个一级缓存,还有 earlySingletonObjects 二级缓存和 singletonFactories 三级缓存。这样即使有循环依赖,Spring 也能正确处理。 + +而且 Spring 的单例是线程安全的,因为用的是 ConcurrentHashMap,多线程访问不会有问题。 + +#### bean + +Bean 本质上就是由 Spring 容器管理的 Java 对象,但它和普通的 Java 对象有很大区别。普通的 Java 对象我们是通过 new 关键字创建的。而 Bean 是交给 Spring 容器来管理的,从创建到销毁都由容器负责。 + +从实际使用的角度来说,我们项目里的 Service、Dao、Controller 这些都是 Bean。比如 UserService 被标注了 `@Service` 注解,它就成了一个 Bean,Spring 会自动创建它的实例,管理它的依赖关系,当其他地方需要用到 UserService 的时候,Spring 就会把这个实例注入进去。 + +`@Primary` 注解标注主数据源,用 `@Qualifier` 来指定备用数据源。 + +当我们直接用 `@Autowired` 注解注入 DataSource 时,Spring 默认会使用 HikariDataSource;当加上 `@Qualifier("secondary")` 注解时,Spring 则会注入 BasicDataSource。 + +#### @Component 和 @Bean 有什么区别? + +首先从使用上来说,`@Component` 是标注在类上的,而 `@Bean` 是标注在方法上的。`@Component` 告诉 Spring 这个类是一个组件,请把它注册为 Bean,而 `@Bean` 则告诉 Spring 请将这个方法返回的对象注册为 Bean。 \ No newline at end of file