Spring注解的原理

news/2025/1/13 7:52:26/

注解(Annotation)在Java中是一种元数据,它可以为代码提供额外的信息,但本身不会影响程序的执行。在Spring框架中,注解被广泛用于标记组件、配置依赖关系以及进行AOP等操作。我们平时是使用注解的场景有很多,原理却知之甚少,下面来详细剖析一下注解的原理

理解注解的原理需要从Java的反射机制开始讲起,对反射不清楚的请先补习一下java反射的原理,(179条消息) 框架的灵魂———反射_public method getdeclaredmethod(string var1, class_t梧桐树t的博客-CSDN博客

注解的实现原理 

Java注解的原理是基于反射机制的。当我们在代码中使用了注解时,这些注解信息会被编译器保存在class文件中。在运行时,Java虚拟机(JVM)加载类时会将类的信息加载到内存中,其中包括注解信息。

注解本身并没有直接的逻辑处理能力,但可以被自定义处理器或框架读取和解析。Spring框架就是利用反射机制读取注解信息,并根据注解提供的元数据进行相应的处理。以下是Spring如何实现注解的基本原理:

  1. 类加载:JVM会在运行时加载类,并将类的信息加载到内存中。包括类的方法、字段、注解等元数据信息。

  2. 注解解析:Spring框架在启动时会扫描指定包路径下的所有类,查找被特定注解标记的类或方法。这个过程通过反射实现,Spring会读取类的字节码信息,并解析其中的注解信息。

  3. 注解处理:Spring根据读取到的注解信息执行相应的处理逻辑。例如,@Component注解用于标记组件类,Spring会将这些组件实例化并加入到应用上下文中,供后续使用。

  4. 依赖注入:在启动过程中,Spring框架会解析@Autowired注解,自动在容器中查找匹配的bean,并将其注入到目标类中。

  5. AOP切面:Spring AOP(面向切面编程)也是通过注解实现的。使用特定的注解标记切点和通知,Spring在运行时根据注解信息进行动态代理。

举例说明 

自定义注解需要使用Java提供的元注解(Meta-Annotation)对注解进行定义。常用的元注解包括:

  • @Target:指定注解的适用范围,可以是类、方法、字段等。
  • @Retention:指定注解的生命周期,可以是源码级别、编译时期或运行时期。
  • @Documented:指定注解是否包含在JavaDoc中。
  • @Inherited:指定注解是否可以被继承。

当解析注解时,首先要定义一个自定义的注解,并为其指定@Target@Retention等元注解。然后,我们可以在需要使用该注解的类或方法上进行标记。接下来,让我们通过一个具体的例子来演示Spring注解的原理和实现过程。

假设我们要开发一个简单的用户管理系统,其中包含用户服务和日志服务。我们将使用自定义注解@Log来标记需要记录日志的方法,并通过AOP切面来实现日志记录功能。

定义自定义注解:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
}

创建用户服务类:

@Service
public class UserService {@Logpublic void createUser(String username, String email) {// 实现创建用户的逻辑System.out.println("创建用户:" + username + ", 邮箱:" + email);}public void deleteUser(int userId) {// 实现删除用户的逻辑System.out.println("删除用户,ID:" + userId);}
}

创建日志切面类:

@Component
@Aspect
public class LogAspect {@Before("@annotation(Log)")public void logBefore(JoinPoint joinPoint) {MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();Method method = methodSignature.getMethod();System.out.println("记录日志:调用方法 " + method.getName() + " 前");}
}

 配置Spring启动类:

@SpringBootApplication
@EnableAspectJAutoProxy
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}


http://www.ppmy.cn/news/990168.html

相关文章

QGraphicsView实现简易地图1『加载离线瓦片地图』

最简单粗暴的加载方式,将每一层级的所有瓦片地图全部加载 注:该方式仅能够在瓦片地图层级较低时使用,否则卡顿!!! 瓦片地图数据来源:水经注-高德地图-卫星地图 瓦片地图瓦片大小:25…

报数游戏、

描述 有n人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来的第几号的那位。。 输入 初始人数n 输出 最后一人的初始编号 输入样例 1 3 输出样例 1 2 输入样例 …

Appium+python自动化(三十五)- 命令启动appium之 appium服务命令行参数(超详解)

简介 前边介绍的都是通过按钮点击启动按钮来启动appium服务,有的小伙伴或者童鞋们乍一听可能不信,或者会问如何通过命令行启动appium服务呢?且听一一道来。 一睹为快 其实相当的简单,不看不知道,一看吓一跳&#xf…

SqlServer读写分离对等发布

SqlServer读写分离对等发布: 对等发布支持多主复制。发布服务器将事务流式传输到拓扑中的所有对等方。所有对等节点可以读取和写入更改,且所有更改将传播到拓扑中的所有节点。 注意点: 1.各服务器的数据库名字要保证一样。 2.发布名称必须保持一致。 3.各服务器必须都是…

ChatGPT 实现前一天

提出需求 个人输入需求: Java实现键盘输入日期 输出前一天,需要考虑润年和非润年,2月是否有29号,大月小月的区分等细节处理,不符合的有对应提示,不使用java包里的封装好的类 ChatGPT4分析出的语义&#xff…

图像中的曲率和梯度概念

图像中的曲率和梯度概念 1、曲率2、梯度 1、曲率 曲率是描述曲线在某点处的弯曲程度的度量指标。对于二维图像上的曲线,可以通过计算曲率来描述其在某一点处的曲线弯曲情况。具体而言,曲率可以通过求曲线的二阶导数来计算,其定义为曲线上某一…

Android Glide预处理preload原始图片到成品resource 预加载RecyclerViewPreloader,Kotlin

Android Glide预处理preload原始图片到成品resource & 预加载RecyclerViewPreloader&#xff0c;Kotlin <uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name"android.permission.READ_MED…

uniAPP 浙政钉 入门手册

uniAPP 如何运行钉钉小程序&#xff1a; 运行钉钉小程序 调试工具导入项目 及 相关平台使用&#xff1a; 专有钉钉 浙政钉 前端 对接流程 常见调试工具&#xff0c;遇到的问题&#xff1a; 采坑记录 下载小程序 IDE 环境配置文件 专有钉钉–环境配置文件