Spring常见注解

Spring常见注解

  • 1. 概述
  • 2. DI(依赖注⼊)相关注解
    • 2.1 @Autowired
    • 2.2 @Bean
    • 2.3 @Qualifier
    • 2.4 @Required (很少使用)
    • 2.5 @Value
    • 2.6 @Lazy
    • 2.7 @Profile

1. 概述

我们都知道Spring最核心的特性就是IOC(控制反转)+ AOP(⾯向切⾯编程),IOC的原理就是实现了一个Spring容器,用来管理所有Spring Bean实例,DI也就是依赖注入,是我们作为开发者需要关心的核心话题,如何注入依赖,注入哪个依赖,是我们需要明确知道的。 很久之前使用xml配置文件来声明一个bean,但现在,使用注解和代码来完成DI的过程。

我们可以使用 org.springframework.beans.factory.annotationorg.springframework.context.annotation 包中的注释来启用 Spring DI 引擎的功能。

2. DI(依赖注⼊)相关注解

2.1 @Autowired

我们可以使用 @Autowired 来标记 Spring 将要解析和注入的依赖项。 我们可以将此注释与构造函数、setter 或字段注入一起使用。

构造器注入:

class Car {Engine engine;@AutowiredCar(Engine engine) {this.engine = engine;}
}

Setter注入

class Car {Engine engine;@Autowiredvoid setEngine(Engine engine) {this.engine = engine;}
}

变量注入

class Car {@AutowiredEngine engine;
}

2.2 @Bean

@Bean 标记实例化 Spring bean 的工厂方法:

@Bean
Engine engine() {return new Engine();
}

当需要返回类型的新实例时,Spring 会调用这些方法。

生成的 bean 与工厂方法同名。 如果我们想以不同的方式命名,我们可以使用此注释的名称或值参数(参数值是参数名称的别名):

@Bean("engine")
Engine getEngine() {return new Engine();
}

这是一种非常常见的bean声明方式,因为很多的bean并不是我们一开始就在代码里定义好的,它可能需要基于运行时环境来进行按需构建。

我们可以自由地声明和定义Bean,并且也可以赋予它自定义的bean名称。

注意,所有用@Bean 注释的方法都必须在@Configuration 类中。

举例

import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
import org.springframework.kafka.config.KafkaListenerContainerFactory;
import org.springframework.kafka.core.*;
import org.springframework.kafka.listener.ConcurrentMessageListenerContainer;import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;@Configuration
public class CloudKafkaConfig {@Resourceprivate AppConfig appConfig;@Beanpublic KafkaTemplate<String, String> kafkaCloudTemplate() {return new KafkaTemplate<>(producerFactory());}@Bean(name = "kafkaCloudContainerFactory")KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<Integer, String>> kafkaCloudContainerFactory() {ConcurrentKafkaListenerContainerFactory<Integer, String> factory = new ConcurrentKafkaListenerContainerFactory<>();factory.setConsumerFactory(consumerFactory());factory.getContainerProperties().setPollTimeout(3000);return factory;}private ProducerFactory<String, String> producerFactory() {return new DefaultKafkaProducerFactory<>(producerConfigs());}private ConsumerFactory<Integer, String> consumerFactory() {return new DefaultKafkaConsumerFactory<>(consumerConfigs());}private Map<String, Object> producerConfigs() {Map<String, Object> props = new HashMap<>(3);props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, appConfig.getKafkaServers());props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);return props;}private Map<String, Object> consumerConfigs() {Map<String, Object> props = new HashMap<>(4);props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, appConfig.getKafkaServers());props.put(ConsumerConfig.GROUP_ID_CONFIG, appConfig.getKafkaGroupId());props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);props.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "100");props.put(ConsumerConfig.REQUEST_TIMEOUT_MS_CONFIG, "30000");props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, "15000");props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG,true);return props;}
}

2.3 @Qualifier

我们使用@Qualifier 和@Autowired 来提供我们想要在不明确情况下使用的bean id 或bean 名称。
例如,以下两个 bean 实现相同的接口:

class Bike implements Vehicle {}class Car implements Vehicle {}

如果 Spring 需要注入一个 Vehicle bean,它会以多个匹配定义结束。 在这种情况下,我们可以使用 @Qualifier 注释显式提供 bean 的名称。

构造器注入

@Autowired
Biker(@Qualifier("bike") Vehicle vehicle) {
this.vehicle = vehicle;
}

Setter注入

@Autowired
void setVehicle(@Qualifier("bike") Vehicle vehicle) {
this.vehicle = vehicle;
}

或者

@Autowired
@Qualifier("bike")
void setVehicle(Vehicle vehicle) {
this.vehicle = vehicle;

变量注入

@Autowired
@Qualifier("bike")
Vehicle vehicle;

这个注解我们可能平常用的不多,但是当一个接口有多个实现类时,它就会经常派上用场!

2.4 @Required (很少使用)

@Required 在 setter 方法上标记我们想要通过 XML 填充的依赖项:

@Required
void setColor(String color) {this.color = color;
}

xml

<bean class="com.baeldung.annotations.Bike"><property name="color" value="green" />
</bean>

@Required 注解是 Spring 框架中的一个注解,用于确保依赖注入的属性必须被设置。如果 Spring 容器在创建 bean 时发现被 @Required 注解标记的属性没有被设置,它会抛出一个 BeanInitializationException,从而阻止 bean 的创建。

使用场景
@Required 注解通常用于确保某些关键属性在配置 bean 时被设置,以防止在 bean 使用过程中出现未初始化的属性导致的错误。

使用方法
@Required 注解通常与 setter 方法一起使用,确保相应的 setter 方法必须被调用以设置属性值。

2.5 @Value

非常常用的一个注解,因为我们很多时候都需要从application.properties或者其他配置文件中来读取配置属性值。

engine.fuelType=petrol@Value("${engine.fuelType}")
String fuelType;

2.6 @Lazy

使用场景

  • 性能优化:对于一些耗资源或启动时间长的 bean,希望在启动时不创建它们,而是在首次使用时才进行创建。
  • 避免循环依赖:延迟初始化某些 bean 可以帮助解决循环依赖问题。
  • 懒加载特性:有时需要根据具体使用场景决定是否创建某个 bean。

使用方法

  • @Lazy 注解可以应用于类、字段、方法和配置方法。

示例
以下是一些使用 @Lazy 注解的示例:

  1. 懒加载类
    当整个类被标记为 @Lazy 时,Spring 容器在启动时不会初始化这个类,而是在第一次需要它时进行初始化。
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;@Component
@Lazy
public class ExpensiveService {public ExpensiveService() {System.out.println("ExpensiveService is initialized");}public void performService() {System.out.println("Performing expensive service...");}
}
  1. 懒加载字段
    在字段级别使用 @Lazy 注解,只有在访问该字段时才会初始化它。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;@Component
public class UserService {@Autowired@Lazyprivate ExpensiveService expensiveService;public void useService() {System.out.println("UserService is calling ExpensiveService");expensiveService.performService();}
}
  1. 懒加载方法
    在方法级别使用 @Lazy 注解,方法返回的 bean 会延迟初始化。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;@Configuration
public class AppConfig {@Bean@Lazypublic ExpensiveService expensiveService() {return new ExpensiveService();}
}

2.7 @Profile

@Profile 注解在 Spring 框架中用于指定 bean 在特定环境(或配置文件)下才会被创建和加载。它可以帮助开发者根据不同的环境(如开发、测试、生产)来加载不同的配置和 bean。

使用场景

  • 环境配置:在不同的环境中加载不同的 bean。
  • 测试和开发:在测试环境中加载模拟(mock)bean,在生产环境中加载实际 bean。
  • 多环境支持:根据环境变量或配置文件动态切换配置。
public interface MessageService {String getMessage();
}@Profile("dev")
@Component
public class DevMessageService implements MessageService {@Overridepublic String getMessage() {return "Hello from Development";}
}@Profile("prod")
@Component
public class ProdMessageService implements MessageService {@Overridepublic String getMessage() {return "Hello from Production";}
}

配置文件方式
除了在代码中设置 spring.profiles.active,也可以在外部配置文件(如 application.properties 或 application.yml)中进行设置。

spring.profiles.active=dev

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/14902.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PySODEvalToolkit 使用笔记

1. 克隆仓库 首先&#xff0c;克隆PySODEvalToolkit仓库到你的本地机器&#xff1a; git clone https://github.com/lartpang/PySODEvalToolkit.git2. 创建虚拟环境 cd PySODEvalToolkit conda create -n pysodeval python3.73. 安装依赖 pip install -r requirements.txt4…

[算法] 优先算法(一): 双指针算法(上)

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (91平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;Java …

SpringBoot2.0.x旧版集成Swagger UI报错Unable to infer base url...解决办法

一、问题描述 1.1项目背景 SpringBoot2.0.9的旧版项目维护开发&#xff0c;集成Swagger-ui2.9.2无法访问的问题。不用想啊&#xff0c;这种老项目是各种过滤器拦截器的配置&#xff0c;访问不到&#xff0c;肯定是它们在作妖。懂得都懂啊&#xff0c;这里交给大家一个排错的办…

Flutter设计模式全面解析:单例模式

谈到设计模式这个“古老”的话题&#xff0c;大家先别急着划走哈&#xff0c;虽然对它再熟悉不过&#xff0c;几乎是最初开始学习编程到现在伴随着我们整个编程生涯&#xff0c;最早 Java、C 语言实现的各种设计模式到现在还会经常有所接触&#xff0c;面试中也是必问的环节&am…

Adobe Camera Raw 11 for Mac/win:摄影后期处理的革命性飞跃

在数字摄影的世界里&#xff0c;RAW格式以其未压缩的原始数据特性&#xff0c;为摄影师提供了更大的后期处理空间。而Adobe Camera Raw 11&#xff0c;作为这一领域的翘楚&#xff0c;以其卓越的性能和创新的功能&#xff0c;为摄影师们带来了前所未有的创作体验。 Adobe Came…

LeetCode450删除二叉搜索树中的节点

题目描述 给定一个二叉搜索树的根节点 root 和一个值 key&#xff0c;删除二叉搜索树中的 key 对应的节点&#xff0c;并保证二叉搜索树的性质不变。返回二叉搜索树&#xff08;有可能被更新&#xff09;的根节点的引用。一般来说&#xff0c;删除节点可分为两个步骤&#xff1…

Linux环境中部署docker私有仓库Registry与远程访问详细流程

目录 前言 1. 部署Docker Registry 2. 本地测试推送镜像 3. Linux 安装cpolar 4. 配置Docker Registry公网访问地址 5. 公网远程推送Docker Registry 6. 固定Docker Registry公网地址 前言 作者简介&#xff1a; 懒大王敲代码&#xff0c;计算机专业应届生 今天给大家聊…

网络安全知识核心20要点

1、什么是SQL注入攻击 概述 攻击者在 HTTP 请求中注入恶意的 SQL 代码&#xff0c;服务器使用参数构建数据库 SQL 命令时&#xff0c;恶意SQL 被一起构造&#xff0c;并在数据库中执行。 注入方法 用户登录&#xff0c;输入用户名 lianggzone&#xff0c;密码‘ or ‘1’’…

揭秘Python的魔法:装饰器的超能力大揭秘 ‍♂️✨

文章目录 Python进阶之装饰器详解1. 引言装饰器的概念与意义装饰器在Python编程中的作用 2. 背景介绍2.1 函数作为对象2.2 高阶函数 3. 装饰器基础3.1 理解装饰器3.2 装饰器的工作原理 4. 带参数的装饰器4.1 为什么需要带参数4.2 实现带参数的装饰器使用函数包裹装饰器使用类实…

TypeScript-泛型

泛型(Generics) 指在定义接口&#xff0c;函数等类型的时候&#xff0c;不预先指定具体的类型&#xff0c;而在使用的时候再指定类型的一种特性&#xff0c;使用泛型可以复用类型并且让类型更加灵活 泛型接口-interface 语法&#xff1a;在 interface 接口类型的名称后面使用…

AI服务器连接解决方案领军企业Astera Labs宣布,将在台湾组建首个位于硅谷以外的Cloud-Scale Interop Lab

AI服务器连接解决方案领军企业Astera Labs宣布&#xff0c;将在台湾组建首个位于硅谷以外的Cloud-Scale Interop Lab&#xff0c;集结中国台湾制造商共同参与。据《工商时报》报道&#xff0c;Astera Labs将与台湾主要ODM客户紧密合作&#xff0c;预期广达、英业达、纬创资通、…

web前端的路径和Servlet注解开发

目录 在web前端的两种路径 绝对路径的两种写法 相对路径 相对路径进阶 使用注解开发Servlet 使用注解开发Servlet的注意事项 使用idea创建servlet模板 在web前端的两种路径 绝对路径的两种写法 1.带网络三要素 http://ip地址:端口号/资源路径 2.不带网络三要素 /资源路…

『哈哥赠书 - 53期』-『深入浅出 Spring Boot 3.x』

⭐️ 《深入浅出 Spring Boot 3.x》 ⭐️ 学习Spring Boot的必读之书 在 Java 后端开发领域&#xff0c;功能强大的 Spring 开源框架不仅是首选&#xff0c;也是事实上的标准。但由于 Spring 存在配置烦琐、部署不易、依赖管理困难等问题&#xff0c;因此基于 Spring 的快速开…

告别传统,拥抱未来——上门回收小程序引领变革

随着科技的飞速发展&#xff0c;我们生活的方方面面都在经历着前所未有的变革。在环保和可持续发展的背景下&#xff0c;传统的废品回收方式已经难以满足现代社会的需求。而上门回收小程序的出现&#xff0c;正以其便捷、高效的特点&#xff0c;引领着废品回收行业的变革。 一、…

【NLPl练习】Transformer起源与发展

Transformer总结 Transformer模型类别分为&#xff1a; 纯Encoder模型纯Decoder模型Encoder-Decoder模型 Transformer模型的本质是预训练语言模型&#xff0c;首先采用自监督学习的方式在大量生语料库上训练&#xff0c;无需人工标注。常用的预训练任务主要有以下两个&#xff…

力扣343 整数拆分 Java版本

文章目录 题目描述代码 题目描述 给定一个正整数 n &#xff0c;将其拆分为 k 个 正整数 的和&#xff08; k > 2 &#xff09;&#xff0c;并使这些整数的乘积最大化。 返回 你可以获得的最大乘积 。 示例 1: 输入: n 2 输出: 1 解释: 2 1 1, 1 1 1。 示例 2: 输…

Leedcode69:x的平方根_Java解法

Problem: 69. x 的平方根 题目描述思路解题方法复杂度Code 题目描述 给你一个非负整数 x &#xff0c;计算并返回 x 的 算术平方根 。 由于返回类型是整数&#xff0c;结果只保留 整数部分 &#xff0c;小数部分将被 舍去 。 注意&#xff1a;不允许使用任何内置指数函数和…

HCIP-Datacom-ARST自选题库__OSPF单选【80道题】

1.OSPFV2是运行在IPV4网络的IGP&#xff0c;OSPFV3是运行在IPV6网络的ICP&#xff0c;OSPFV3与OSPFv2的报文类型相同&#xff0c;包括Hello报文、DD报文、LSR报文、LSU报文和LSAck报文。关于OSPFv3报文&#xff0c;以下哪个说法是正确的 OSPFv3使用报文头部的认证字段完成报文…

NVIDIA Jetson AGX Orin虚拟显示器安装

NVIDIA Jetson AGX Orin虚拟显示器安装 ​ 在orin上使用过程中。由于没有连接显示屏导致无法正常使用远程桌面工具进行代码调试。可使用虚拟显示器解决上述问题。 1、安装远程桌面软件并进行相关配置 ​ 安装远程桌面软件参考各个远程桌面软件官网介绍。 2、开启界面共享 …

【LeetCode】数组——双指针法

1 双指针法 1.1 介绍 双指针法是一种常用的算法技巧&#xff0c;通常用于处理数组或链表中的问题。它使用两个指针&#xff0c;通常一个从数组的开始位置遍历&#xff0c;另一个从数组的末尾位置开始遍历&#xff0c;根据问题的不同&#xff0c;这两个指针可以同时移动&#…