【Spring 篇】深入浅出:用Spring注解开发的奇妙之旅

在这里插入图片描述

在编程的世界里,Spring框架如同一位慈祥的导师,为我们打开了无尽可能性的大门。而在Spring的广袤领域中,注解是我们最亲密的伙伴之一。本篇博客将深入浅出地介绍使用Spring注解进行开发的奇妙之旅,为你解开注解的神秘面纱。

前奏:认识Spring框架

首先,让我们简单了解一下Spring框架。Spring是一个全栈式的Java开发框架,它提供了广泛的功能,包括依赖注入、面向切面编程、数据访问等。Spring的核心思想是IoC(控制反转)和AOP(面向切面编程),它使得我们能够更加灵活、模块化地构建应用程序。

注解入门

在过去,我们可能会通过XML配置来使用Spring框架,但是随着时间的推移,注解成为了更为流行的选择。注解是一种元数据,它提供了对类、方法、字段等元素进行标记的能力,通过在代码中添加注解,我们能够告诉Spring框架如何处理我们的类和方法。

让我们从最简单的注解开始:

@Component
public class HelloWorld {
    public void greet() {
        System.out.println("Hello, World!");
    }
}

在这个例子中,@Component注解告诉Spring框架将HelloWorld类注册为一个组件,使得Spring能够管理它的生命周期,并在需要时创建它的实例。

依赖注入的魔法

依赖注入是Spring框架的一项重要特性,通过它,我们能够将一个对象的依赖关系交给Spring来管理。这样一来,我们的代码就变得更加松散耦合,更容易维护和测试。

让我们看一个简单的例子:

@Component
public class Car {
    private Engine engine;

    @Autowired
    public Car(Engine engine) {
        this.engine = engine;
    }

    public void start() {
        engine.start();
        System.out.println("Car started!");
    }
}

@Component
public class Engine {
    public void start() {
        System.out.println("Engine started!");
    }
}

在这个例子中,Car类有一个对Engine的依赖关系。通过在构造方法上加上@Autowired注解,我们告诉Spring框架需要注入一个Engine实例。当我们调用car.start()时,Spring会自动将Engine实例注入到Car中,实现依赖注入的魔法。

切面编程的艺术

面向切面编程是Spring框架的另一项强大功能,它使得我们能够在不修改原有代码的情况下,通过横切关注点(cross-cutting concerns)来增强应用程序的功能。

让我们通过一个日志切面的例子来了解切面编程:

@Aspect
@Component
public class LoggingAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("Before method: " + joinPoint.getSignature().getName());
    }

    @After("execution(* com.example.service.*.*(..))")
    public void logAfter(JoinPoint joinPoint) {
        System.out.println("After method: " + joinPoint.getSignature().getName());
    }
}

在这个例子中,@Aspect注解表示这是一个切面类,通过在方法上使用@Before@After注解,我们定义了在执行某个包中所有方法前后打印日志的逻辑。通过在Spring配置中启用切面,这些日志将自动地被添加到相应的方法中,而无需修改原有的业务逻辑。

注解的默契舞蹈

Spring框架提供了许多内置的注解,它们为我们提供了极大的便利。下面是一些常用的注解及其作用:

  • @Component: 用于标记一个类为Spring组件,由Spring自动管理。
  • @Autowired: 用于进行依赖注入。
  • @Service, @Repository, @Controller: 用于标记分别为服务、仓库和控制器的Spring组件。
  • @Configuration: 用于定义配置类,替代XML配置文件。
  • @Bean: 用于定义Spring Bean。
  • @Scope: 用于指定Bean的作用域。
  • @Value: 用于注入外部配置文件的值。
  • @RequestMapping: 用于处理HTTP请求的映射。

让我们通过一个完整的例子来展示这些注解的默契舞蹈:

@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.getUserById(id);
        return ResponseEntity.ok(user);
    }

    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        userService.createUser(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(user);
    }
}

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public User getUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }

    public void createUser(User user) {
        userRepository.save(user);
    }
}

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

在这个例子中,@Controller注解标记UserController为Spring MVC的控制器,通过@RequestMapping指定了映射路径。@Service注解标记UserService为服务组件,而@Repository注解标记UserRepository为Spring的数据仓库。

通过@Autowired注解,我们将UserServiceUserRepository注入到UserControllerUserService中,实现了依赖注入。这种通过注解来声明组件和配置的方式,使得代码更加清晰,减少了样板代码,提高了开发效率。

自定义注解的魔法

除了Spring提供的内置注解外,我们还可以通过自定义注解来实现更灵活的功能。自定义注解为我们提供了在代码中添加自定义元数据的能力,从而实现更加精细的控制和逻辑。

让我们通过一个简单的例子来看看如何自定义注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogExecutionTime {
}

在这个例子中,我们定义了一个名为LogExecutionTime的注解,它标记在方法上,并在运行时保留。接下来,我们可以使用这个注解来记录方法的执行时间:

@Service
public class MyService {

    @LogExecutionTime
    public void performTimeConsumingOperation() {
        // 执行一些耗时的操作
    }
}

通过结合AOP和自定义注解,我们可以在方法执行前后添加逻辑,实现更加灵活的功能。例如,我们可以在LogAspect切面类中定义在方法执行前后记录时间的逻辑:

@Aspect
@Component
public class LogAspect {

    @Around("@annotation(LogExecutionTime)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();

        Object proceed = joinPoint.proceed();

        long endTime = System.currentTimeMillis();
        System.out.println(joinPoint.getSignature() + " executed in " + (endTime - startTime) + "ms");

        return proceed;
    }
}

在这个例子中,@Around注解表示在目标方法执行前后都会执行,通过@annotation(LogExecutionTime)指定了切入点为标记有LogExecutionTime注解的方法。通过这种方式,我们成功地在performTimeConsumingOperation方法执行前后记录了执行时间。

注解开发的小白教程

对于初学者而言,注解开发可能会显得有些晦涩难懂。但是只要理解了一些基本概念,就能够轻松地踏入注解的奇妙世界。

1. 注解的基本语法

注解的基本语法相对简单,通常以@符号开头,后面跟着注解的名称和一对圆括号。有些注解还需要在圆括号中添加一些参数。例如:

@AnnotationName(parameter = "value")
public class MyClass {
    // class body
}

2. 注解的作用范围

注解可以标记在类、方法、字段等不同的元素上,具体取决于注解的@Target注解定义。例如,@Target(ElementType.METHOD)表示该注解只能标记在方法上。

3. 注解的生命周期

注解的生命周期由@Retention注解定义,通常有三个生命周期:

  • RetentionPolicy.SOURCE: 注解仅在源代码中存在,编译时会被忽略。
  • RetentionPolicy.CLASS: 注解在源代码和编译后的字节码中存在,但在运行时会被忽略。
  • RetentionPolicy.RUNTIME: 注解在源代码、编译后的字节码和运行时都存在,可以在运行时通过反射获取。

4. 注解的处理方式

Spring框架通过使用AOP(面向切面编程)来处理注解。在底层,Spring通过扫描类路径中的组件,识别并处理标记有特定注解的类和方法。这种方式使得开发者无需手动处理注解,而是通过配置和约定实现自动化。

5. 常用的Spring注解

在Spring中,有一些常用的注解是我们开发中经常会遇到的,例如@Component@Autowired@Service@Repository@Controller等。了解这些注解的作用和用法,能够更好地理解和使用Spring框架。

结语

通过本篇博客,我们深入浅出地探索了使用Spring注解进行开发的奇妙之旅。从最基础的注解入门,到依赖注入、切面编程、内置注解、自定义注解,一步步揭开了注解的神秘面纱。希望通过这篇博客,你能更好地理解和运用Spring注解,为自己的项目注入更多灵活和强大的功能。在注解的世界里,让我们一起跳起默契的舞蹈,创造出更加优雅的代码!

作者信息

作者 : 繁依Fanyi
CSDN: https://techfanyi.blog.csdn.net
掘金:https://juejin.cn/user/4154386571867191

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024年远控软件年度盘点:安全、稳定、功能之选

这目录 前言2024年热门远控软件ToDesk向日葵TeamViewerAnyDeskSplashtopAirDroidChrome Remote DesktopMicrosoft远程桌面RayLinkParallels Access 远程控制软件如何选择&#xff1f;1、功能性2、安全性3、易用性4、稳定性 未来展望与建议结语 前言 随着信息技术不断发展&…

使用命令行方式搭建uni-app + Vue3 + Typescript + Pinia + Vite + Tailwind CSS + uv-ui开发脚手架

使用命令行方式搭建uni-app Vue3 Typescript Pinia Vite Tailwind CSS uv-ui开发脚手架 项目代码以上传至码云&#xff0c;项目地址&#xff1a;https://gitee.com/breezefaith/uniapp-vue3-ts-scaffold 文章目录 使用命令行方式搭建uni-app Vue3 Typescript Pinia V…

移动端对大批量图片加载的优化方法(一)

移动端对大批量图片加载的优化方法&#xff08;一&#xff09;iOS 本篇主要从iOS开发中可以使用到的对大批量图片加载的优化方法进行整理。 1.异步加载 将图片加载任务放在后台线程中进行&#xff0c;避免阻塞主线程&#xff0c;这样可以保证应用的响应性和流畅性&#xff1…

视频剪辑方法:智能转码从视频到图片序列,高效转换攻略

在视频编辑和后期处理中&#xff0c;经常要将视频转换为图片序列&#xff0c;以便进行单独编辑或应用。下面一起来看云炫AI智剪如何批量智能转码的方法&#xff0c;高效地将视频转换为图片序列。 视频转为序列图片缩略图效果 视频转为序列图片的效果图&#xff0c;画面清晰&a…

vue3 img图片怎么渲染

在 Vue3 中加载图片&#xff08;img&#xff09;src地址时&#xff0c;出现无法加载问题。网上很多都建议使用 require 加载相对路径&#xff0c;如下&#xff1a; <img :src"require(../assets/img/icon.jpg)"/>但是按照这种方式加载又会报错如下&#xff1a;…

Access、Trunk、Hybrid接口接收发送数据帧标签剥离区分

以太网二层接口类型 Access Trunk Hybrid 总结&#xff1a; VLAN原理最全最详细讲解&#xff01;彻底搞懂VLAN打和摘tag过程

亚马逊鲲鹏自动测评系统:提升店铺流量与销售的利器

在跨境电商领域&#xff0c;提升店铺流量、排名以及销售业绩一直是卖家们关注的焦点。近期&#xff0c;亚马逊鲲鹏自动测评系统的推出备受关注&#xff0c;成为卖家们提升竞争力的得力工具。据真实客户反馈&#xff0c;该系统不仅能够全自动化批量操作&#xff0c;而且内置了防…

.NET学习教程一——.net基础定义+VS常用设置

一、定义 .NET分为.NET平台和.NET框架。 .NET平台&#xff08;厨房&#xff09;.NET FrameWork 框架&#xff08;柴米油盐酱醋茶&#xff09; .NET平台&#xff08;中国移动联通平台&#xff09;.NET FrameWork 框架&#xff08;信号塔&#xff09; .NET平台基于.NET Fra…

记一次JSF异步调用引起的接口可用率降低

前言 本文记录了由于JSF异步调用超时引起的接口可用率降低问题的排查过程&#xff0c;主要介绍了排查思路和JSF异步调用的流程&#xff0c;希望可以帮助大家了解JSF的异步调用原理以及提供一些问题排查思路。本文分析的JSF源码是基于JSF 1,7.5-HOTFIX-T6版本。 起因 问题背景…

含中间直流的三相电力电子变压器PET仿真模型

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 背景&#xff1a; 目前高压电网中应用的绝大多数电力变压器都属于传 统电力变压器&#xff0c;传统变压器的优势在于工艺简单、安全性 较强。但传统变压器本身的弊端也非常突出&#xff0c;占地大、重 量大&…

0108作业

#include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {this->setWindowTitle("腾讯会议");this->resize(470,800);//设置界面大小this->setFixedSize(470,800);//锁定界面大小this->setStyleSheet("background-color:w…

FPGA状态机学习

Verilog 是硬件描述语言&#xff0c;硬件电路是并行执行的&#xff0c;当需要按照流程或者步骤来完成某个功能时&#xff0c;代码中通常会使用很多个 if 嵌套语句来实现&#xff0c;这样就增加了代码的复杂度&#xff0c;以及降低了代码的可读性&#xff0c;这个时候就可以使用…

办公文档,私人专用

一、安装Minio 1.1、创建文件夹&#xff0c;并在指定文件夹中下载minio文件 cd /opt mkdir minio cd minio touch minio.log wget https://dl.minio.io/server/minio/release/linux-amd64/minio1.2、赋予minio文件执行权限 chmod 777 minio1.3、启动minio ./minio server /…

利用矩阵特征值解决微分方程【1】

目录 一. 特征值介绍 二. 单变量常微分方程 三. 利用矩阵解决微分方程问题 四. 小结 4.1 矩阵论 4.2 特征值与特征向量内涵 4.3 应用 一. 特征值介绍 线性代数有两大基础问题&#xff1a; 如果A为对角阵的话&#xff0c;那么问题就很好解决。需要注意的是&#xff0c;矩…

14.网络编程入门和网络应用开发

网络编程入门 计算机网络基础 计算机网络是独立自主的计算机互联而成的系统的总称&#xff0c;组建计算机网络最主要的目的是实现多台计算机之间的通信和资源共享。今天计算机网络中的设备和计算机网络的用户已经多得不可计数&#xff0c;而计算机网络也可以称得上是一个“复…

媒介pr工作内容有哪些,小红书达人投放总结!

随着新媒体技术的发展&#xff0c;很多人都不约而同的选择成为一名新媒体从业人员&#xff0c;这其中就包括媒介PR。当涉及媒介投放技巧时&#xff0c;我们需要思考许多关键因素&#xff0c;使我们的公关活动取得理想结果。今天我们就来分享一下媒介pr工作内容有哪些&#xff0…

CTF-PWN-沙箱逃脱-【seccomp和prtcl-2】

文章目录 沙箱逃脱prtcl题HITCON CTF 2017 Quals Impeccable Artifactflag文件对应prctl函数检查源码思路exp 沙箱逃脱prtcl题 HITCON CTF 2017 Quals Impeccable Artifact flag文件 此时的flag文件在本文件夹建一个即可 此时的我设置的flag为 对应prctl函数 第一条是禁止…

答疑解惑:核技术利用辐射安全与防护考核

前言 最近通过了《核技术利用辐射安全与防护考核》&#xff0c;顺利拿到了合格证。这是从事与辐射相关行业所需要的一个基本证书&#xff0c;考试并不难&#xff0c;在此写篇博客记录一下主要的知识点。 需要这个证书的行业常见的有医疗方面的&#xff0c;如放疗&#xff0c;…

Python实战化采集淘宝1688京东详情,API接口开发系列

Python实战化采集淘宝、京东详情和API接口开发是一个涉及多个步骤和技术的过程。下面是一个简化的教程&#xff0c;帮助你开始这个过程。 1. 准备工作 首先&#xff0c;确保你已经安装了Python&#xff0c;并且了解基本的Python编程。此外&#xff0c;你可能需要安装一些库&a…
最新文章