springboot开发的常用注解总结-配置组件类注解
Spring Boot 提供了许多注解,这些注解大大简化了 Spring 应用的配置和开发过程。以下是一些常见的 Spring Boot注解及其作用。
目录
- 配置组件类 (Configure Component )
- @Configuration
- 解释:
- Demo Code:
- 更深度使用:
- @ComponentScan
- 解释:
- Demo Code:
- 更深度使用:
- @Scope
- 解释:
- Demo Code:
- 1. Singleton(单例)
- 2. Prototype(原型)
- 3. Request(请求)
- 4. Session(会话)
- 5. Application(应用)
- 6. WebSocket(WebSocket 会话)
- 引申
- @Lazy
- 解释:
- Demo Code:
- 更深度使用:
- @Conditional
- 解释:
- Demo Code 自定义一个Condition
- @Import
- 详解
- 使用 Demo
配置组件类 (Configure Component )
@Configuration
解释:
@Configuration 注解用于指示一个类声明了一个或多个 @Bean 方法,并且可能被 Spring 容器作为 Bean
定义的源进行处理。它允许你通过 Java 配置的方式来替代 XML 配置文件。被 @Configuration 注解的类内部可以包含多个
@Bean 注解的方法,这些方法将返回对象,这些对象会作为 Spring 应用上下文中的 Bean。
被@Configuration 注解的类通常被称为 配置类。
Demo Code:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Beanpublic MyService myService() {return new MyServiceImpl();}
}class MyService {// Service methods
}class MyServiceImpl implements MyService {// Implementation details
}
更深度使用:
-
可以结合 @Import 注解来导入其他配置类。
-
使用 @Profile 注解来指定配置类只在特定的环境下激活。
-
可以使用 @Enable* 注解来启用特定的 Spring 功能(如 @EnableTransactionManagement)。
@ComponentScan
解释:
@ComponentScan 注解用于告诉 Spring 框架在包及其子包中查找被
@Component、@Service、@Repository、@Controller 等注解标记的类,并将这些类注册为 Spring应用上下文中的 Bean。
Demo Code:
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@Configuration
@ComponentScan(basePackages = "com.example.demo")
public class AppConfig {// Configuration details
}// In package com.example.demo
@Service
public class MyService {// Service implementation
}
更深度使用:
-
可以通过 excludeFilters 和 includeFilters 属性来过滤扫描到的类。
-
可以设置 lazyInit 属性来指定是否延迟初始化扫描到的 Bean。
@Scope
解释:
@Scope 注解用于指定 Spring 容器中 Bean 的作用域。Spring
提供了几种作用域,包括单例(Singleton)、原型(Prototype)、会话(Session)、请求(Request)等。
Demo Code:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.web.context.WebApplicationContext;@Configuration
public class AppConfig {@Bean@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)public MySessionBean mySessionBean() {return new MySessionBean();}
}class MySessionBean {// Session scoped bean
}
1. Singleton(单例)
解释:在 Spring 容器中,每个 Bean
只有一个实例,且这个实例会被存储在单例缓存中。对于所有的请求和会话,都会返回这个共享的实例。这是默认的作用域。
Demo:由于 Singleton 是默认作用域,所以通常不需要显式指定。但如果要强调其单例性质,可以这样写:
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public MySingletonBean mySingletonBean() {return new MySingletonBean();
}
2. Prototype(原型)
解释:每次从 Spring 容器中请求该 Bean 时,都会创建一个新的实例。这意味着每个请求都会得到一个新的 Bean 实例。
Demo:
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public MyPrototypeBean myPrototypeBean() {return new MyPrototypeBean();
}
3. Request(请求)
解释:每次 HTTP 请求都会创建一个新的 Bean 实例,并且该实例仅在当前 HTTP 请求内有效。这通常用于 Web 应用程序中,与
Servlet 请求的生命周期相关联。
注意:要使用请求作用域,你需要在一个 Web 环境中,并且 Spring 的 DispatcherServlet 正在运行。
Demo(假设在 Web 环境中):
@Bean
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public MyRequestBean myRequestBean() {return new MyRequestBean();
}
4. Session(会话)
解释:每个 HTTP 会话都会创建一个新的 Bean 实例,且该实例仅在当前会话内有效。这也适用于 Web 应用程序。
Demo(假设在 Web 环境中):
@Bean
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public MySessionBean mySessionBean() {return new MySessionBean();
}
5. Application(应用)
解释:在 ServletContext 的生命周期内,每个 Bean 都只有一个实例。这通常用于存储跨多个用户会话的共享数据。但是,请注意,Spring Framework 本身并没有直接提供名为“Application”的内置作用域。这通常是通过在 ServletContext 中直接存储数据或使用 @ServletContextAttribute 注解来实现的。
Demo:由于 Spring 没有直接提供“Application”作用域,这里不展示具体的 Bean 定义,但你可以通过实现自己的 Scope 接口或使用 ServletContextListener 来管理跨会话的数据。
6. WebSocket(WebSocket 会话)
解释:对于使用 WebSocket 的应用程序,Spring 4.2 引入了 WebSocket 会话作用域。这允许你将 Bean 的生命周期与 WebSocket 会话绑定。
Demo:WebSocket 会话作用域的使用依赖于 Spring 的 WebSocket 支持,并且不常见于所有应用程序。因此,这里不提供具体的 Demo,但你可以查看 Spring WebSocket 文档以获取更多信息。
引申
在Spring框架中,当你配置一个Bean的作用域为请求(WebApplicationContext.SCOPE_REQUEST)、会话(WebApplicationContext.SCOPE_SESSION)或其他非单例作用域时,并且你希望将这个Bean注入到一个单例Bean中时,你会遇到一个问题:单例Bean的生命周期与请求/会话Bean的生命周期不一致。为了解决这个问题,Spring引入了作用域代理(Scoped Proxy)的概念。
proxyMode = ScopedProxyMode.TARGET_CLASS 是配置作用域代理的一种方式,它告诉Spring为这个Bean创建一个代理对象,而不是直接创建Bean的实例。这个代理对象将负责在每次需要时获取目标Bean的实例,从而实现了作用域的隔离。
具体来说,ScopedProxyMode.TARGET_CLASS 使用CGLIB库来创建目标类的子类作为代理。这意味着代理对象可以无缝地替代目标类对象,而不需要实现额外的接口(与 ScopedProxyMode.INTERFACES 不同,后者要求目标类实现至少一个接口)。
示例
假设你有一个会话作用域的Bean,你希望将其注入到一个单例Bean中:
@Bean
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public MySessionBean mySessionBean() {return new MySessionBean();
}@Service
public class MySingletonService {@Autowiredprivate MySessionBean mySessionBean; // 这里注入的是代理对象public void doSomething() {// 在这里调用mySessionBean的方法时,实际上是通过代理对象来访问当前会话的MySessionBean实例mySessionBean.doSomethingInSessionScope();}
}
@Lazy
解释:
@Lazy 注解用于指示 Spring 容器在初始化时不立即创建该 Bean 的实例,而是在首次使用时才创建。既延时加载。
Demo Code:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;@Configuration
public class AppConfig {@Bean@Lazypublic MyLazyBean myLazyBean() {return new MyLazyBean();}
}class MyLazyBean {// Lazy initialized bean
}
更深度使用:
@Lazy 可以与 @Autowired 结合使用,但需要注意,当使用 @Autowired 注入 @Lazy 标注的 Bean
时,默认行为可能会因 Spring 版本而异(可能需要额外的设置或注解)。
@Conditional
解释:
@Conditional 注解用于条件化地创建 Bean。它允许基于满足特定条件的情况下来注册 Bean。通常与自定义的 Condition
实现类一起使用。
Demo Code 自定义一个Condition
为了写一个自定义@Conditional的demo,我们需要定义一个实现org.springframework.context.annotation.Condition接口的类,并在一个配置类中使用@Conditional注解来引用这个条件类。下面是一个简单的示例,其中我们将基于一个系统属性来决定是否创建某个Bean。
首先,我们定义一个条件类OnPropertyCondition,它检查系统属性中是否存在某个特定的键:
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;public class OnPropertyCondition implements Condition {private static final String PROPERTY_NAME = "myapp.feature.enabled";@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {Environment env = context.getEnvironment();// 检查系统属性或环境变量中是否存在该属性,并且其值为trueString property = env.getProperty(PROPERTY_NAME);return Boolean.TRUE.toString().equals(property);}
}
然后,我们创建一个配置类,使用@Conditional注解来引用我们的条件类,并根据条件决定是否创建Bean:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Conditional;@Configuration
public class ConditionalConfig {@Bean@Conditional(OnPropertyCondition.class)public FeatureBean featureBean() {return new FeatureBean();}// FeatureBean 的实现public static class FeatureBean {// 实现细节public void doSomething() {System.out.println("Feature is enabled and doing something...");}}
}
@Import
@Import 注解在 Spring
框架中用于导入其他配置类,使得你可以在一个配置类中组合和重用多个配置类。这对于模块化配置特别有用,因为它允许你将配置分散到多个类中,然后在需要的地方通过
@Import 注解将它们组合在一起。
详解
用途:
将其他配置类导入到当前配置类中,以便重用它们的 @Bean 定义、@ComponentScan 扫描路径等。
位置:
通常用于 @Configuration 注解的类上。
参数:
@Import 可以直接指定要导入的配置类(Class 类型)。 也可以指定 ImportSelector 或
ImportBeanDefinitionRegistrar 接口的实现类,以实现更复杂的导入逻辑。 注意:当使用 @Import
导入配置类时,这些配置类中定义的 Bean 也会被 Spring 容器管理,就像它们在当前配置类中定义的一样。
使用 Demo
假设我们有两个配置类,DatabaseConfig 和 SecurityConfig,我们想要在一个主配置类 AppConfig
中将它们都导入。
DatabaseConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class DatabaseConfig {@Beanpublic DataSource dataSource() {// 创建并返回 DataSource 实例return new DataSource(); // 注意:这里应该是实际的 DataSource 实现,这里只是示例}
}
SecurityConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class SecurityConfig {@Beanpublic SecurityManager securityManager() {// 创建并返回 SecurityManager 实例return new SecurityManager(); // 注意:这里应该是实际的安全管理器实现,这里只是示例}
}
AppConfig.java
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;@Configuration
@Import({DatabaseConfig.class, SecurityConfig.class})
public class AppConfig {// 这里不需要定义任何 Bean,因为所有的 Bean 都已经在 DatabaseConfig 和 SecurityConfig 中定义了// AppConfig 仅仅是一个组合配置类,它通过 @Import 注解导入了其他配置类
}
相关文章:
springboot开发的常用注解总结-配置组件类注解
Spring Boot 提供了许多注解,这些注解大大简化了 Spring 应用的配置和开发过程。以下是一些常见的 Spring Boot注解及其作用。 目录 配置组件类 (Configure Component )Configuration解释:Demo Code:更深度使用&#x…...
DataX 最新版本安装部署
1、下载 git clone gitgithub.com:alibaba/DataX.git 2、打包 mvn -U clean package assembly:assembly -Dmaven.test.skiptrue...

【架构】应用保护
这篇文章总结一下应用保护的手段。如今说到应用保护,更多的会想到阿里的sentinel,手段丰富,应用简单。sentinel的限流、降级、熔断,可以自己去试一下,sentinel主要通过配置实现功能,不难。sentinel的简介放…...

从核心到边界:六边形、洋葱与COLA架构的深度解析
文章目录 1 引言2 软件架构3 架构分类4 典型的应用架构4.1 分层架构4.2 CQRS4.3 六边形架构4.4 洋葱架构4.5 DDD 5 COLA架构设计5.1 分层设计5.2 扩展设计5.3 规范设计5.3.1 组件规范5.3.2 包规范5.3.3 命名规范 6 COLA架构总览7 小结 1 引言 软件的首要技术使命:管…...

04-Fastjson反序列化漏洞
免责声明 本文仅限于学习讨论与技术知识的分享,不得违反当地国家的法律法规。对于传播、利用文章中提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,本文作者不为此承担任何责任,一旦造成后果请自行承担&…...
ABC365(A-D)未补
A - Leap Year(模拟) 题意:给定一个数字n,如果n不是4的倍数,输出365;如果n是4的倍数但不是100的倍数,输出366;如果n是100的倍数但不是400的倍数,输出365;如果…...
Python用png生成不同尺寸的图标
Kimi生成 from PIL import Imagedef generate_icon(source_image_path, output_image_path, size):with Image.open(source_image_path) as img:# 转换图片为RGBA模式,确保有透明通道if img.mode ! RGBA:img img.convert(RGBA)# 调整图片大小到指定尺寸img img.r…...

1688中国站获得工厂档案信息 API
公共参数 名称类型必须描述keyString是免费申请调用key(必须以GET方式拼接在URL中)secretString是调用密钥api_nameString是API接口名称(包括在请求地址中)[item_search,item_get,item_search_shop等]cacheString否[yes,no]默认y…...

定时任务框架 xxl-job
🍓 简介:java系列技术分享(👉持续更新中…🔥) 🍓 初衷:一起学习、一起进步、坚持不懈 🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏 🍓 希望这篇文章对你有所帮助,欢…...

C/C++关键字大全
目录 一、const 二、static 三、#define 和 typedef 四、#define 和 inline 五、#define 和 const 六、new 和 malloc 七、const 和 constexpr 八、volatile 九、extern 十、前置 和后置 十一、atomic 十二、struct 和 class 一、const 1、const 关键字可用于定义…...

ROS2 Linux Mint 22 安装教程
前言: 本教程在Linux系统上使用。 一、linux安装 移动硬盘安装linux:[LinuxToGo教程]把ubuntu装进移动固态,随时随用以下是我建议安装linux mint版本的清单: 图吧工具箱:https://www.tbtool.cn/linux mint: https://…...

快速将网站从HTTP升级为HTTPS
在当今数字化的世界中,网络安全变的越来越重要,HTTPS(超文本传输安全协议)不仅能够提供加密的数据传输,还能增强用户信任度,提升搜索引擎排名,为网站带来多重益处。所以将网站从HTTP升级到HTTPS…...

Qt程序移植至Arm开发板
目录 1.工具准备: 系统调试工具SecureCRT 虚拟机安装linux(Ubuntu) 交叉编译工具链 ARM 端Qt 环境(Qt-5.7.1) 1) linux processor SD安装 2)交叉编译工具链配置 2.编译Qt工程: 2.0 交叉编译 依赖库源码,生成动…...

删除分区 全局索引 drop partition global index Statistics变化
1.不一定unusable,可以先删除data (index 再删除过程中会更新结构)再drop/truncate. ---------------------- CREATE TABLE interval_sale ( prod_id NUMBER(6) , cust_id NUMBER , time_id DATE ) PARTITION BY RANGE (time_i…...

git回退未commit、回退已commit、回退已push、合并某一次commit到另一个分支
文章目录 1、git回退未commit2、git回退已commit3、git回退已push的代码3.1 直接丢弃某一次的push3.2 撤销push后,不丢弃改动,重新修改后要再次push 4、合并某一次commit到另一个分支 整理几个工作上遇到的git问题。 1、git回退未commit git回退未comm…...

yolov8pose 部署rknn(rk3588)、部署地平线Horizon、部署TensorRT,部署工程难度小、模型推理速度快,DFL放后处理中
特别说明:参考官方开源的yolov8代码、瑞芯微官方文档、地平线的官方文档,如有侵权告知删,谢谢。 模型和完整仿真测试代码,放在github上参考链接 模型和代码。 之前写了yolov8、yolov8seg、yolov8obb 的 DFL 放在模型中和放在后处理…...
程序员找工作之操作系统面试题总结分析
程序员在找工作面试时,操作系统方面可能会被问到的问题涵盖了多个核心知识点和概念。以下是对这些面试问题的总结和分析: 1. 核心硬件与体系结构 微机的核心部件:询问微机硬件系统中最核心的部件是什么(CPU)。处理机…...
TypeScript 迭代器和生成器详解
目录 迭代器(Iterators) 生成器(Generators) 使用场景 for..of vs. for..in 语句 for..of 循环 for..in 循环 区别总结 注意事项 总结 在 TypeScript 中,迭代器(Iterators)和生成器&am…...

echarts 极坐标柱状图 如何定义柱子颜色
目录 echarts 极坐标柱状图 如何定义柱子颜色问题描述方式一 在 series 数组中定义颜色方式二 通过 colorBy 和 color 属性配合使用 echarts 极坐标柱状图 如何定义柱子颜色 本文将分享在使用 echarts 的 极坐标柱状图 时,如何自定义柱子的颜色。问题本身并不难解决…...

JavaScript模块化
JavaScript模块化 一、CommonJS规范1、在node环境下的模块化导入、导出 2、浏览器环境下使用模块化browserify编译js 二、ES6模块化规范1、在浏览器端的定义和使用2、在node环境下简单使用方式一:方式二: 3、导出数据4、导入数据5、数据引用问题 一、Com…...

python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...

MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...

Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...