3、spring注解学习(组件注册)——@Scope注解设置组件作用域、@Lazy单例对象懒加载设置
1、spring主配置类注册一个Person组件
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.stereotype.Controller; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.Scope; import com.atguigu.bean.Person; //配置类==配置文件 @Configuration //告诉Spring这是一个配置类 @ComponentScan(value="com.atguigu", //指定要扫描的包 excludeFilters= {@Filter(type=FilterType.ANNOTATION,classes= {Controller.class})} //指定以某种规则排除扫描哪些组件 /*includeFilters= {@Filter(type=FilterType.ANNOTATION,classes= {Controller.class})}, //指定以某种规则只扫描哪些组件 useDefaultFilters = false //includeFilters必须配合useDefaultFilters = false(默认值是true)来使用*/ ) public class MainConfig { //给容器注册一个Bean;类型为返回值类型(bean的id默认是用方法名作为id) //@Bean("")增加内容后指定bean的id @Bean("person") public Person person() { return new Person("张三", 19); } }
2、在测试类中写测试方法
/** * 测试Scope注解设置组件作用域 */ @Test public void test02() { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class); Person p1 = (Person) applicationContext.getBean("person"); Person p2 = (Person) applicationContext.getBean("person"); System.out.println(p1 == p2); }
测试后输出为
由此说明从容器中取出的Person为同一个对象,即注册的person的scope(作用域)为singleton(单例)
spring注册的组件默认为单例模式
3、修改主配置类person组件的作用域为prototype(多例模式)
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.stereotype.Controller; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.Scope; import com.atguigu.bean.Person; //配置类==配置文件 @Configuration //告诉Spring这是一个配置类 @ComponentScan(value="com.atguigu", //指定要扫描的包 excludeFilters= {@Filter(type=FilterType.ANNOTATION,classes= {Controller.class})} //指定以某种规则排除扫描哪些组件 /*includeFilters= {@Filter(type=FilterType.ANNOTATION,classes= {Controller.class})}, //指定以某种规则只扫描哪些组件 useDefaultFilters = false //includeFilters必须配合useDefaultFilters = false(默认值是true)来使用*/ ) public class MainConfig { //给容器注册一个Bean;类型为返回值类型(bean的id默认是用方法名作为id) //@Bean("")增加内容后指定bean的id @Bean("person") @Scope("prototype") //多例模式 public Person person() { return new Person("张三", 19); } }
再次运行测试方法后结果为:
则说明作用域为propotype的组件每次从容器中取出都是一个新的对象
在注解类中设置scope也是一样的方式:
4、单例对象懒加载设置(懒加载只针对单例对象)
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.stereotype.Controller; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Scope; import com.atguigu.bean.Person; //配置类==配置文件 @Configuration //告诉Spring这是一个配置类 @ComponentScan(value="com.atguigu", //指定要扫描的包 excludeFilters= {@Filter(type=FilterType.ANNOTATION,classes= {Controller.class})} //指定以某种规则排除扫描哪些组件 /*includeFilters= {@Filter(type=FilterType.ANNOTATION,classes= {Controller.class})}, //指定以某种规则只扫描哪些组件 useDefaultFilters = false //includeFilters必须配合useDefaultFilters = false(默认值是true)来使用*/ ) public class MainConfig { //给容器注册一个Bean;类型为返回值类型(bean的id默认是用方法名作为id) //@Bean("")增加内容后指定bean的id @Bean("person") @Lazy //单例对象懒加载,第一次获取的时候才创建,而不是IOC容器初始化时创建 public Person person() { return new Person("张三", 19); } }
总结:
singleton :表示在spring容器中的单例,通过spring容器获得该bean时总是返回唯一的实例
单例对象在没有设置懒加载时候是在springIOC容器创建时就创建(只创建一次)
设置懒加载之后springIOC容器创建时不创建,而是在第一次获取该单例对象时才创建(只创建一次,懒加载只对象单例对象有效)
prototype:表示每次获得bean都会生成一个新的对象
多例对象是在每次获取的时候才创建
request : 表示在一次http请求内有效(只适用于web应用)
session : 表示在一个用户会话内有效(只适用于web应用)
globalSession : 表示在全局会话内有效(只适用于web应用)
在多数情况,我们只会使用singleton和prototype两种scope,如果在spring配置文件内未指定scope属性,默认为singleton。
单例的原因有二:
1、为了性能。
2、不需要多例。
多例主要用在controller中
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)