spring的scope为prototype的bean的正确使用方法

2024-05-26 19:48

本文主要是介绍spring的scope为prototype的bean的正确使用方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

此博文可配合 BGDI 组件实现简单Spring IOC容器及其依赖注入特性。搭配 解决 Java 反射时对象之间的循环依赖问题 解决 bean 对象实例之间的循环依赖问题。

 

引用博客

spring的bean的作用域有 singleton(无状态),prototype(有状态),session,request 等,本来以为很简单,但实际面试中,90%的人根本就不知道如何使用,其中不乏工作5,6年以上的,只知道有这几个作用域,由此可以看出大部分java开发人员基础真是差啊。

很多人看教程里面,使用prototype作用域的bean代码里面,获取bean的方法都是用appContext.getBean方法获取,但实际工作编码中,我们一般是通过方法的参数注入。

@Service
@Scope(value="prototype")
public class MainServices {// ...
}

如下,每次注入新的MainServices实例:

@GetMapping("/test3")
public HashMap<String, Object> test2(@Autowired MainServices s) {// ...
}

但要在一个controller里面注入一个多例的service需要怎么实现?(工作中不应该这样用,而是应该通过参数注入)

如下:

@RestController
public class MainController {@AutowiredMainServices services;
}

很明显controller只有一个,service也有只一个,这样定义是不能达到效果的!自己测试一下就知道。

正确的方法是如下,需要指定使用代理如果注入的是接口可以用INTERFACES,否则用TARGET_CLASS

@Service
@Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class MainServices {// ...
}

这样spring就会注入一个代理类,然后每次调用的时候会根据你的作用域去获取bean。只有不是singleton的bean,注入的都是代理类。

很简单的一个知识点,我想说明的是,看教程一定要自己尝试一下,并了解他的工作原理,思考ioc,aop,作用域的关系。

所以你知道为什么在controller里面注入request没有线程安全问题了吧?!

@Autowired
HttpServletRequest request;

这里request返回的是类名是com.sun.proxy.$Proxy62,很明显使用的jdk的动态代理。

 


@Scope 注解使用

全局配置

@ComponentScan(basePackages = {"com.jaemon.sdk"}, scopedProxy = ScopedProxyMode.TARGET_CLASS)
public class SpingBootApplication {// ...
}

默认值: ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;

类级别配置

// 如果注入的是接口, 可以使用 ScopedProxyMode.INTERFACES, 否则使用 ScopedProxyMode.TARGET_CLASS
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.INTERFACES)
public class BizService {// ...
}@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class UserServiceImpl implements IUserService {// ...
}

如果在 @ComponentScan 中设置了全局配置, 则 @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)可以无需设置 proxyMode 属性的值, 默认 scopedProxy 使用的是全局配置的值。

 

代码验证

注入类

@Service
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class BizService {private String uniqueKey;public BizService() {this.uniqueKey = UUID.randomUUID().toString().replace("-", "").toUpperCase();}public String uniqueKey() {return this.uniqueKey;}
}

注入接口

public interface IUserService {String userId();
}@Service
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.INTERFACES)
public class UserServiceImpl implements IUserService {private String userId;public UserServiceImpl() {this.userId = UUID.randomUUID().toString().replace("-", "").toUpperCase();}@Overridepublic String userId() {return userId;}
}
@RestController
@RequestMapping("/api")
@Slf4j
public class MyController {// 注入类@Autowiredprivate BizService bizService;// 注入接口@Autowiredprivate IUserService userService;@GetMapping(value = "/query")public Response query() {String uniqueKey = bizService.uniqueKey();String userId = userService.userId();return Response.success(userId, uniqueKey);}
}

重复请求 query 接口, 如果返回结果中 userId 和 uniqueKey 每次都不一样, 说明 scope=prototype 配置生效

 

参考地址

  • spring的scope为prototype的bean的正确使用方法

这篇关于spring的scope为prototype的bean的正确使用方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1005427

相关文章

SQL Server 查询数据库及数据文件大小的方法

《SQLServer查询数据库及数据文件大小的方法》文章介绍了查询数据库大小的SQL方法及存储过程实现,涵盖当前数据库、所有数据库的总大小及文件明细,本文结合实例代码给大家介绍的非常详细,感兴趣的... 目录1. 直接使用SQL1.1 查询当前数据库大小1.2 查询所有数据库的大小1.3 查询每个数据库的详

聊聊springboot中如何自定义消息转换器

《聊聊springboot中如何自定义消息转换器》SpringBoot通过HttpMessageConverter处理HTTP数据转换,支持多种媒体类型,接下来通过本文给大家介绍springboot中... 目录核心接口springboot默认提供的转换器如何自定义消息转换器Spring Boot 中的消息

python之uv使用详解

《python之uv使用详解》文章介绍uv在Ubuntu上用于Python项目管理,涵盖安装、初始化、依赖管理、运行调试及Docker应用,强调CI中使用--locked确保依赖一致性... 目录安装与更新standalonepip 安装创建php以及初始化项目依赖管理uv run直接在命令行运行pytho

Springboot项目构建时各种依赖详细介绍与依赖关系说明详解

《Springboot项目构建时各种依赖详细介绍与依赖关系说明详解》SpringBoot通过spring-boot-dependencies统一依赖版本管理,spring-boot-starter-w... 目录一、spring-boot-dependencies1.简介2. 内容概览3.核心内容结构4.

Spring Boot 整合 SSE(Server-Sent Events)实战案例(全网最全)

《SpringBoot整合SSE(Server-SentEvents)实战案例(全网最全)》本文通过实战案例讲解SpringBoot整合SSE技术,涵盖实现原理、代码配置、异常处理及前端交互,... 目录Spring Boot 整合 SSE(Server-Sent Events)1、简述SSE与其他技术的对

Spring Security 前后端分离场景下的会话并发管理

《SpringSecurity前后端分离场景下的会话并发管理》本文介绍了在前后端分离架构下实现SpringSecurity会话并发管理的问题,传统Web开发中只需简单配置sessionManage... 目录背景分析传统 web 开发中的 sessionManagement 入口ConcurrentSess

Java整合Protocol Buffers实现高效数据序列化实践

《Java整合ProtocolBuffers实现高效数据序列化实践》ProtocolBuffers是Google开发的一种语言中立、平台中立、可扩展的结构化数据序列化机制,类似于XML但更小、更快... 目录一、Protocol Buffers简介1.1 什么是Protocol Buffers1.2 Pro

Java实现本地缓存的四种方法实现与对比

《Java实现本地缓存的四种方法实现与对比》本地缓存的优点就是速度非常快,没有网络消耗,本地缓存比如caffine,guavacache这些都是比较常用的,下面我们来看看这四种缓存的具体实现吧... 目录1、HashMap2、Guava Cache3、Caffeine4、Encache本地缓存比如 caff

C#使用Spire.XLS快速生成多表格Excel文件

《C#使用Spire.XLS快速生成多表格Excel文件》在日常开发中,我们经常需要将业务数据导出为结构清晰的Excel文件,本文将手把手教你使用Spire.XLS这个强大的.NET组件,只需几行C#... 目录一、Spire.XLS核心优势清单1.1 性能碾压:从3秒到0.5秒的质变1.2 批量操作的优雅

MyBatis-Plus 与 Spring Boot 集成原理实战示例

《MyBatis-Plus与SpringBoot集成原理实战示例》MyBatis-Plus通过自动配置与核心组件集成SpringBoot实现零配置,提供分页、逻辑删除等插件化功能,增强MyBa... 目录 一、MyBATis-Plus 简介 二、集成方式(Spring Boot)1. 引入依赖 三、核心机制