Spring--注解

一、简介

Spring注解是一种元数据形式的代码,用于提供配置信息,从而减少XML配置文件的使用。Spring框架提供了一系列的注解,用于简化Spring应用程序的开发。通过使用这些注解,开发者可以在不编写大量XML配置的情况下,实现对Spring容器中bean的声明和管理、自动装配依赖、声明事务管理等功能。

二、常用注解

  1. @Component:表示一个类是Spring容器管理的组件,可以被自动扫描并注册到Spring应用上下文中。
  2. @Controller:是@Component的特化,用于标注控制层的组件,处理用户请求和返回响应。
  3. @RestController:是@Controller和@ResponseBody的组合,简化了RESTful Web服务的编写。
  4. @Service:是@Component的特化,用于标注服务层的组件。
  5. @Repository:是@Component的特化,用于标注数据访问层的组件,通常与数据库交互。
  6. @Configuration:表示一个类是配置类,可以包含一个或多个@Bean注解的方法。
  7. @Bean:表示一个方法产生一个bean,该方法的返回值将被注册到Spring应用上下文中。
  8. @Autowired:用于自动注入依赖关系,它可以应用于字段、构造函数、setter方法等。
  9. @Qualifier:与@Autowired结合使用,指定要注入的确切的bean实例。
  10. @RequestMapping:用于映射Web请求到控制器的处理方法,可以指定URL模式、HTTP方法等。
  11. @PathVariable:用于从URL的一部分中提取变量值,并将其作为方法参数。
  12. @ResponseBody:指示方法的返回值应该直接写入HTTP响应体中,通常与@RequestMapping一起使用。
  13. @Transactional:用于声明事务的边界,确保事务的一致性和原子性。
  14. @EnableTransactionManagement:启用声明式事务管理。

三、元注解

Spring框架中的元注解是指那些用于注解其他注解的注解。它们提供了一种机制来定义新的注解,并指定这些新注解的行为和作用范围。Spring提供了几个核心的元注解,这些元注解可以用来创建自定义注解,以下是一些常用的Spring元注解:

  1. @Target:指定自定义注解可以应用于哪些Java元素,如类、方法、构造函数、字段或注解等。它接受ElementType枚举的一个或多个值作为参数,常用的枚举值有:
    • ElementType.TYPE:说明该注解只能被声明在一个类前;
    • ElementType.FIELD:说明该注解只能被声明在一个类的字段前;
    • ElementType.METHOD:说明该注解只能被声明在一个类的方法前;
    • ElementType.PARAMETER:说明该注解只能被声明在一个方法参数前;
    • ElementType.CONSTRUCTOR:说明该注解只能声明在一个类的构造方法前;
    • ElementType.LOCAL_VARIABLE:说明该注解只能声明在一个局部变量前;
    • ElementType.ANNOTATION_TYPE:说明该注解只能声明在一个注解类型前;
    • ElementType.PACKAGE:说明该注解只能声明在一个包名前。
  2. @Retention:确定自定义注解在何种生命周期内有效。它有三个可能的值:
    • RUNTIME:表示注解在运行时依然存在;
    • CLASS:表示注解仅在编译后的.class文件中保留;
    • SOURCE:表示注解仅在源代码中有效,编译时会被丢弃。
  3. @Documented:指示Javadoc工具应该记录自定义注解。当你希望在生成的API文档中包含自定义注解时,应该使用这个元注解。
  4. @Inherited:表示自定义注解可以被子类继承。如果一个注解被标注为@Inherited,那么其父类上的该注解也会出现在子类上。

四、注解的原理

Spring框架中的注解原理基于Java的反射API和代理技术,主要涉及以下几个方面:

  1. 注解扫描:

    • Spring容器启动时,会根据@ComponentScan注解指定的基础包路径,扫描类路径下所有带有特定注解(如@Component、@Service、@Repository、@Controller等)的类。
    • 这些注解通常会通过@Component或其特化注解来标记Spring容器应该管理的组件。
  2. Bean的实例化和注册:

    • 被扫描到的带有Spring管理注解的类将被实例化。如果该类有无参构造函数,Spring会使用默认无参构造函数创建实例;如果没有无参构造函数,可能会使用CGLIB等字节码操作库进行实例化。
    • 创建的实例会被注册到Spring容器中,以便之后进行依赖注入。
  3. 依赖注入:

    • Spring容器会根据注解如@Autowired、@Inject、@Resource等来确定依赖关系,并通过反射机制将依赖注入到目标Bean中。
    • 如果依赖是由方法参数或者构造函数指定的,Spring会尝试匹配相应类型的Bean进行注入。
    • 如果依赖是字段,Spring会直接设置字段的值。
  4. 代理创建:

    • 对于需要AOP(面向切面编程)功能的Bean,Spring会创建一个代理对象。这个代理对象会拦截对目标Bean的调用,并在适当的时机执行通知逻辑。
    • 代理可以是JDK动态代理(仅适用于实现了接口的类)或者基于CGLIB的代理(适用于所有类,包括抽象类和没有实现接口的类)。
  5. Bean的生命周期管理:

    • Spring容器负责管理Bean的整个生命周期。在Bean初始化时,会调用初始化方法(如@PostConstruct注解的方法)。
    • 在Bean销毁时,会调用清理方法(如@PreDestroy注解的方法)。
  6. 事件发布和监听器机制:

    • Spring容器在Bean的生命周期事件发生时,会发布相应的事件,比如ContextRefreshedEvent、ContextClosedEvent等。
    • 可以注册监听器(Listener)来响应这些事件,从而实现一些自定义的逻辑。

五、自定义注解

自定义注解是通过使用@interface关键字来创建的。自定义注解可以用来为类、方法、变量等添加元数据信息。自定义注解本身也可以被其他注解修饰。以下是创建和使用自定义注解的基本步骤:

  1. 定义注解:使用@interface关键字来定义一个注解类型。可以指定注解的保留策略(@Retention)、允许的目标(@Target)等。
import java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME)  // 注解在运行时依然存在
@Target(ElementType.FIELD) // 注解作用于字段上
@Documented  // 注解将包含在JavaDoc中
@Inherited   // 注解来允许注解被继承
public @interface CustomAnnotation {String value();String name() default "defaultName";  // 为注解的元素提供默认值
}
  1. 使用注解:在类、方法、变量等元素上使用定义好的注解。
public class ExampleClass {@CustomAnnotation("exampleValue")private String exampleField;
}
  1. 处理注解:在程序运行时,可以使用反射API来检测注解,并根据注解的信息执行相应的逻辑。
import java.lang.reflect.Field;public class AnnotationProcessor {public static void processAnnotations(Object object) throws IllegalAccessException {Class<?> clazz = object.getClass();for (Field field : clazz.getDeclaredFields()) {if (field.isAnnotationPresent(CustomAnnotation.class)) {CustomAnnotation annotation = field.getAnnotation(CustomAnnotation.class);String value = annotation.value();System.out.println("Found annotation with value: " + value);}}}
}

六、自定义注解与AOP整合

在Spring框架中,通过将自定义注解和AOP结合使用,可以对业务逻辑进行非侵入式的增强。下面是如何创建自定义注解并将其应用于切面的详细步骤:

  1. 定义自定义注解:首先,需要定义一个自定义注解,该注解可以包含一些元数据,如目标方法的名称、执行顺序等。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogExecutionTime {// 可以定义更多的属性,例如优先级等
}
  1. 创建切面类:接着,创建一个切面类,并定义通知(Advice),通知是指在切点匹配的方法执行前后或抛出异常时执行的代码块。
@Aspect
public class LoggingAspect {// 定义切点表达式,匹配带有LogExecutionTime注解的方法@Pointcut("@annotation(com.example.annotation.LogExecutionTime)")public void methodsAnnotatedWithLogExecutionTime() {}// 在目标方法前执行的通知@Before("methodsAnnotatedWithLogExecutionTime()")public void logBefore(JoinPoint joinPoint) {long start = System.currentTimeMillis();System.out.println("Starting method: " + joinPoint.getSignature().getName());}// 在目标方法后执行的通知@After("methodsAnnotatedWithLogExecutionTime()")public void logAfter(JoinPoint joinPoint) {long end = System.currentTimeMillis();System.out.println("Ending method: " + joinPoint.getSignature().getName() + " in " + (end - start) + "ms");}
}
  1. 启用AOP支持:在Spring配置文件中,或者使用Java配置来启用AOP支持。
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {// 其他配置...
}
  1. 使用自定义注解:最后,将自定义注解应用于需要被切面处理的方法上。
@Service
public class SomeService {@LogExecutionTimepublic void someBusinessMethod() {// 业务逻辑}
}

在上述示例中,LogExecutionTime注解被定义并用于标记特定的方法。LoggingAspect切面类定义了两个通知方法:logBefore和logAfter,它们分别在带有LogExecutionTime注解的方法执行前后执行。通过@EnableAspectJAutoProxy注解,Spring容器会自动为切面生成代理对象,从而使得通知能够在目标方法执行时被触发。通过这种方式,可以非常灵活地为不同的业务逻辑添加额外的行为,而无需修改原有代码,这正是AOP的强大之处。

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

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

相关文章

代码随想录day23(2)二叉树:从中序与后序遍历序列构造二叉树(leetcode106)

题目要求&#xff1a;根据一棵树的中序遍历与后序遍历构造二叉树。 思路&#xff1a;408的经典题目&#xff0c;思路和手撕的思路差不多&#xff0c;先从后序中找到根节点&#xff0c;再从中序中找到此节点&#xff0c;然后分割成左右子树&#xff0c;记录一下左右子树的节点个…

PyQt5使用

安装Pyqt5信号与槽使用可视化界面编辑UI (Pyside2)ui生成之后的使用(两种方法)1 ui转化为py文件 进行import2 动态调用UI文件 安装Pyqt5 pip install pyqt5-tools这时候我们使用纯代码实现一个简单的界面 from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButto…

2024 年(第 12 届)“泰迪杯”数据挖掘挑战赛——B 题:基于多模态特征融合的图像文本检索完整思路与源代码分享

一、问题背景 随着近年来智能终端设备和多媒体社交网络平台的飞速发展&#xff0c;多媒体数据呈现海量增长 的趋势&#xff0c;使当今主流的社交网络平台充斥着海量的文本、图像等多模态媒体数据&#xff0c;也使得人 们对不同模态数据之间互相检索的需求不断增加。有效的信…

Rocket MQ 从入门到实践

为什么要使用消息队列&#xff0c;解决什么问题&#xff1f;&#xff08;消峰、解藕、异步&#xff09; 消峰填谷 客户端》 网关 〉 消息队列》秒杀服务 异步解耦 消息队列中的重要概念理解。&#xff08;主题、消费组、队列&#xff0c;游标&#xff1f;&#xff09; 主题&…

新手向-从VNCTF2024的一道题学习QEMU Escape

[F] 说在前面 本文的草稿是边打边学边写出来的&#xff0c;文章思路会与一个“刚打完用户态 pwn 题就去打 QEMU Escape ”的人的思路相似&#xff0c;在分析结束以后我又在部分比较模糊的地方加入了一些补充&#xff0c;因此阅读起来可能会相对轻松&#xff08;当然也不排除这是…

Transformer总结

1.Transform背景介绍 1.1Transform的优势 相比于之前占领市场的LSTM和GRU模型&#xff0c;Transformer有两个显著的优势&#xff1a; &#xff08;1&#xff09;Transform能够使用分布式GPU进行并行训练&#xff0c;提升模型训练效率 &#xff08;2&#xff09; 在分析预测…

zookeeper基础学习之六: zookeeper java客户端curator

简介 Curator是Netflix公司开源的一套zookeeper客户端框架&#xff0c;解决了很多Zookeeper客户端非常底层的细节开发工作&#xff0c;包括连接重连、反复注册Watcher和NodeExistsException异常等等。Patrixck Hunt&#xff08;Zookeeper&#xff09;以一句“Guava is to Java…

【算法刷题 | 数组】3.12(二分查找、移除元素、有序数组的平方、长度最小的子数组、螺旋矩阵2)

文章目录 1.二分查找1.1题目1.2思路&#xff08;核心&#xff1a;区间的定义&#xff09;1.3左闭右闭1.4左闭右开1.5总结 2.移除元素2.1题目2.1思路2.2.1暴力解法2.2.2双指针法 23总结 3.有序数组的平方3.1题目3.2思路3.2.1暴力解法3.2.2双指针法 4.长度最小的子数组4.1题目4.2…

Linux中文件和目录管理(创建删除移动复制)

目录 1——一次建立一个或多个目录&#xff1a;mkdir ​2——创建一个空文件&#xff1a;touch 3——移动和重命名&#xff1a;mv 4——复制文件和目录&#xff1a;cp 5—— 删除目录和文件&#xff1a;rmdir和rm 在学习文件与目录的管理的一些命令之前&#xff0c;我们先…

深度学习-面经(part2、CNN)

2 CNN 对图像&#xff08;不同的数据窗口数据&#xff09;和滤波矩阵做内积&#xff08;逐个元素相乘再求和&#xff09;的操作就是所谓的『卷积』操作。 卷积神经网络由输入层、卷积层、激励层、池化层、全连接层组成。 ① 最左边: 数据输入层&#xff0c;对数据做一些处理…

安装vscode及插件

一.环境准备 安装vscode&#xff0c;官网地址&#xff1a;https://code.visualstudio.com安装插件&#xff1a; Chinese (Simplified)&#xff0c;为 VS Code 提供本地化界面&#xff0c;按下“CtrlShiftP”组合键以显示“命令面板”&#xff0c;然后键入“display”以筛选并显…

【划重点】小程序开发难哭了?别怕,大数据揭秘教科书般的小白必看攻略!

当我们在微信的海洋中航行&#xff0c;偶尔会看到一些令人眼前一亮的小程序。它们或简洁实用&#xff0c;或游戏娱乐&#xff0c;或商业推广&#xff0c;各具魅力。但你是否曾好奇过&#xff0c;这些看似简单的小程序背后&#xff0c;隐藏着怎样的开发秘密&#xff1f;今天&…

数字后端 EDA 软件分享

数字后端 EDA 软件分享 推荐这几家的EDA工具吧&#xff0c;虽说我也支持国产工具&#xff0c;但是我还是选择了这几家的工具 apache cadence mentor synopsys 下图我现在用的eda环境&#xff0c;利用网上的资源&#xff0c;自己独立在vmware上搭建好的EDA环境 除去pdk&#…

tmux终端复用器

tmux使用手册 会话与进程需求痛点tmux作用使用场景安装tmux常用命令在tmux中编译代码多个显示器分辨率的tmux attach出现窗口不匹配的问题 会话与进程 命令行的经典使用方式&#xff1a; 用户打开一个终端窗口&#xff08;terminal window&#xff09;&#xff1b;用户在终端…

从政府工作报告探究计算机行业发展

从政府工作报告探计算机行业发展 政府工作报告作为政府工作的全面总结和未来规划&#xff0c;不仅反映了国家整体的发展态势&#xff0c;也为各行各业提供了发展的指引和参考。随着信息技术的快速发展&#xff0c;计算机行业已经成为推动经济社会发展的重要引擎之一。因此&…

计算机考研|怎么备考「科软」?

学好408和考研数学就可以了 大家对于科软已经回到了理性的区间&#xff0c;很难再出现刚开始的300分上科软的现象&#xff0c;也不会再出现388分炸穿地心的现象。 如果大家想报考科软&#xff0c;我觉得一定要认真对待复习&#xff0c;不要抱有抄底的心态去复习。 众所周知&am…

7.JavaWebHTML:构建数字世界的语言和结构

目录 导语&#xff1a; 第一部分&#xff1a;Web概念与作用 1.1 Web的定义 1.2 Web的作用 1.3 JavaWeb 第二部分&#xff1a;HTML概念与内容 2.1 HTML的定义 2.2 HTML的内容 第三部分&#xff1a;HTML的作用 3.1 HTML的作用 3.2 HTML在现代Web开发中的角色 …

[Redis]——主从同步原理(全量同步、增量同步)

目录 Redis集群&#xff1a; 主从同步原理&#xff1a; replid和offset: 全量同步和增量同步&#xff1a; repl_baklog文件&#xff1a; 主从集群的优化&#xff1a; Redis集群&#xff1a; 部署多台Redis我们称之为Redis集群&#xff0c;他有一个主节点(负责写操作)&…

爱普生晶振发布RTC模块晶振(压电侠)

爱普生晶振一直以”省&#xff0c;小&#xff0c;精”技术作为资深核心&#xff0c;并且已经建立了一个原始的垂直整合制造模型&#xff0c;可以自己创建独特的核心技术和设备&#xff0c;使用这些作为基地的规划和设计提供独特价值的产品. 世界领先的石英晶体技术精工爱普生公…

中国联通智慧矿山行业解决方案

中国联通国际公司以其全球化服务能力&#xff0c;针对矿山行业的特殊挑战提供了定制化的解决方案&#xff0c;尤其是在网络通信基础设施搭建和智能应用部署方面&#xff0c;助力企业克服远程作业环境下的通信难题&#xff0c;并有效拓展海外市场。 对于矿山类企业而言&#xf…