快速上手Spring注解、SpringAop

1 Spring 注解的使用

1 IOC 的概念

IOC(Inversion of Control):控制反转。

  • 使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转。通俗的讲就是“将new对象的权利交给Spring,我们从Spring中获取对象使用即可

Spring技术对 IOC 思想进行了实现

  • Spring提供了一个容器,称为IOC容器,用来充当IoC思想中的“外部”
  • IOC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean

DI(Dependency Injection):依赖注入

  • 在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入。

2 使用简单的案例实现注解的使用

案例的代码文件的结构:

在这里插入图片描述

(1)dao层:

package com.xbf.dao;public interface BookDao {void saveBook();
}

(2)service层:

package com.xbf.service;public interface BookService {void insertBook();
}

(3)其他实现类

@Configuration :注解用于标记一个类为配置类,表示该类包含Bean的定义。

@ComponentScan :告诉Spring 哪个packages 的用注解标识的类 会被spring自动扫描并且装入bean容器。

@Configuration //标记该类为spring配置类
@ComponentScan({"com.xbf.dao","com.xbf.service"})
//如果扫描多个类,形如:
// @ComponentScan({"a", "b"})
//简单理解就是,传入一个静态数组
public class SpringConfig {}

@Componet : 在Spring框架中,@Component注解是一个非常核心的概念,它用于将类标记为Spring容器中的一个Bean。这个注解告诉Spring,当应用启动时,需要在ApplicationContext中创建这个类的一个实例。这个过程是自动的,不需要显式编写代码来创建对象。

@Component
public class BookDaoImpl implements BookDao {@Overridepublic void saveBook() {System.out.println("我是BookDaoImpl类的saveBook()方法");}
}

@Autowired :在Spring框架中,@Autowired注解是实现依赖注入(DI)的重要工具。它可以自动地将定义好的Bean注入到Spring容器中的其他Bean中。这个注解可以用于成员变量、方法和构造函数上,从而省去了手动编写大量的获取依赖和赋值代码。

@Component
public class BookServiceImpl implements BookService {@Autowiredprivate BookDao bookDao;@Overridepublic void insertBook() {bookDao.saveBook();System.out.println("我是BookServiceImpl类的方法insert()");}
}

代码运行:

public class App {public static void main(String[] args) {//加载核心配置文件ClassPathXmlApplicationContext ioc = newClassPathXmlApplicationContext("Spring-Context.xml");//从ioc 容器中获取bean对象//BookDao bookDao = (BookDao) ioc.getBean("bookDao");//bookDao.addBook();// 获取 BookService 实例BookService bookService = (BookService) ioc.getBean("bookService");// 调用 BookService 的 insertBook 方法bookService.insertBook();}
}

运行结果:

在这里插入图片描述


2 SpringAOP 的使用

1 AOP 的基本概念

AOP(Aspect Oriented Programming):面向切面编程,一种编程范式,指导开发者如何组织程序结构
**作用:**在不惊动原始设计的基础上为其进行功能增强。
**Spring理念:**无入侵式/无侵入式
**原理:**动态代理
应用:1. 日志 2. 异常捕获、处理 3. 监控统计代码 4. 记录过程。

一些重要的概念:

  1. 连接点(JoinPoint):正在执行的方法,例如:update()、delete()、select()等都是连接点。
  2. 切入点(Pointcut):进行功能增强了的方法,例如:update()、delete()方法,select()方法没有被增强所以不是切入点,但是是连接点。
    • 在SpringAOP中,一个切入点可以只描述一个具体方法,也可以匹配多个方法。
    • 一个具体方法:com.xbf.dao包下的BookDao接口中的无形参无返回值的save方法。
    • 匹配多个方法:所有的save方法,所有的get开头的方法,所有以Dao结尾的接口中的任意方法,所有带有一个参数的方法。
  3. 通知(Advice):在切入点前后执行的操作,也就是增强的共性功能。
    • 在SpringAOP中,功能最终以方法的形式呈现。
  4. 通知类:通知方法所在的类叫做通知类。
  5. 切面(Aspect):描述通知与切入点的对应关系,也就是哪些通知方法对应哪些切入点方法。

2 AOP 的案例实现

  写一个计算器功能:计算加除法。并且用日志方式打印传递的参数、和结果、结束后通知用户计算完成!如果出现异常打印异常信息。完成步骤如下:

  1. 导入aop相关坐标
  2. 创建配置类进行Spring注解包扫描
  3. 定义业务接口与实现类
  4. 定义通知类,制作通知方法
  5. 定义切入点表达式、配置切面(绑定切入点与通知关系)
  6. 在配置类中开启AOP功能

案例代码的结构:
在这里插入图片描述


(1)导入AOP相关坐标

  在 pom.xml 文件中,引入相关依赖:

<!-- Spring 框架的核心模块,提供了 Spring 上下文和依赖注入功能 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency><!-- Spring 测试模块,提供了测试支持和集成 --><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.2.10.RELEASE</version></dependency><!-- AspectJ 织入器,用于支持 Spring AOP 编程模型 --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.5</version></dependency><!-- JUnit 测试框架,用于编写和运行测试用例 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency>

(2)创建相关类

  • service 层:

接口类:

package com.xbf.service;
public interface JiSuanQi {//加法int add(int a, int b);//减法int sub(int a, int b);//乘法int mul(int a, int b);//除法int div(int a, int b);
}

实现类:

package com.xbf.service.impl;
import org.springframework.stereotype.Component;@Component
public class JiSuanQiImpl implements com.xbf.service.JiSuanQi {@Overridepublic int add(int a, int b) {return a + b;}@Overridepublic int sub(int a, int b) {return a - b;}@Overridepublic int mul(int a, int b) {return a * b;}@Overridepublic int div(int a, int b) {return a / b;}
}
  • 核心配置类
package com.xbf.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@Configuration
@ComponentScan({"com.xbf.service","com.xbf.advice"})
@EnableAspectJAutoProxy //开启 Spring 的 AspectJ 自动代理功能,支持 AOP
public class SpringConfig {}
  • 通知类
package com.xbf.advice;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.Arrays;@Component
@Aspect //通知类
public class MyAdvice {@Pointcut("execution(* com.xbf.service.impl.JiSuanQiImpl.*(int, int))")public void pointcut(){};//1.前置通知@Before("pointcut()")public void before(JoinPoint joinPoint) {System.out.println("参数:" + Arrays.toString(joinPoint.getArgs()));System.out.println("开始计算");}//2.后置通知@After("pointcut()")public void after() {System.out.println("计算结束");}//3.返回通知@AfterReturning(value = "pointcut()", returning = "result")public void afterReturning(Object result) {System.out.println("计算结果:" + result);}//4 异常通知@AfterThrowing(value = "pointcut()", throwing = "e")public void afterThrowing(Throwable e) {System.out.println("异常:" + e.getMessage());}
}

@Pointcut 注解的解释:

 @Pointcut("execution(* com.xbf.service.impl.JiSuanQiImpl.*(int, int))")public void pointcut(){};
上式:AspectJ 切点表达式,用于定义一个切点(pointcut)。这个切点表达式指定了在哪些方法执行时应用通知。下面是对这段代码的详细解释:@Pointcut("execution(* com.xbf.service.impl.JiSuanQiImpl.*(int, int))"):这是一个注解,用于定义一个切点。@Pointcut 注解是 AspectJ 框架中的一个特性,它允许你定义一个方法作为切点,然后在其他通知注解(如 @Before、@After、@Around 等)中引用这个切点。"execution(* com.xbf.service.impl.JiSuanQiImpl.*(int, int))":这是切点表达式的具体内容。它的含义是:匹配 com.xbf.service.impl.JiSuanQiImpl 包中的任意类的任意方法,这些方法接收两个 int 类型的参数。execution 是 AspectJ 中最常用的切点指示器,用于指定方法的执行作为切点。这个切点表达式定义了一个非常具体的切点,它只匹配 JiSuanQiImpl 类中的那些接收两个 int 参数的方法。在这个切面类 MyAdvice 中,这个切点被用于四个不同的通知注解(@Before、@After、@AfterReturning、@AfterThrowing),这意味着在JiSuanQiImpl 类的这些特定方法执行之前、之后、返回结果后以及抛出异常后,都会执行相应的通知方法。
  • 快速生成测试类:

在这里插入图片描述

在这里插入图片描述

  JUnit是一个用于编写和运行可重复的自动化测试的开源测试框架,它是单元测试框架的xUnit架构的一个实例。JUnit主要有两个版本:JUnit 4和JUnit 5。

  • JUnit 4:这是JUnit的一个较早期版本,它支持Java 5及以上版本。JUnit 4引入了注解的使用,使得测试用例的编写更加简洁和直观

  • JUnit 5:这是JUnit的最新版本,它在设计上与JUnit 4相比有了重大的改进。JUnit 5的主要目标是支持现代Java开发实践,包括对Java 8及更高版本的支持。
    在这里插入图片描述

默认会在 src/Test 目录下生成。

package com.xbf.service.impl;import com.xbf.config.SpringConfig;
import com.xbf.service.JiSuanQi;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class JiSuanQiTest {@Autowiredprivate JiSuanQi jiSuanQi;@Testpublic void add() {//System.out.println("加法");System.out.println(jiSuanQi.add(2,4));}@Testpublic void sub() {System.out.println(jiSuanQi.sub(5,9));}@Testpublic void mul() {}@Testpublic void div() {//System.out.println(jiSuanQi.div(5,9));double n = jiSuanQi.div(5,9);double m = jiSuanQi.div(5,0);}
}

注解的解释:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
Java中的两个注解:用于配置JUnit测试框架与Spring框架的集成。@RunWith(SpringJUnit4ClassRunner.class):
这个注解是JUnit框架提供的,用于指定测试运行器(Runner)。
SpringJUnit4ClassRunner是Spring框架提供的一个测试运行器,它允许在JUnit测试中使用Spring的依赖注入和事务管理等功能。
通过这个注解,JUnit会自动加载Spring的应用上下文(Application Context),并在测试类中注入Spring管理的Bean。@ContextConfiguration(classes = SpringConfig.class):
这个注解也是Spring框架提供的,用于指定Spring应用上下文的配置类。
SpringConfig.class 是一个配置类,通常包含了Spring框架的各种配置,如Bean的定义、扫描包路径、数据库连接等。
通过这个注解,JUnit会在运行测试之前加载 SpringConfig 类,并根据其中的配置初始化Spring应用上下文。
这两个注解通常一起使用,确保JUnit测试能够在Spring容器的环境中运行,从而可以使用Spring的依赖注入和其他功能来测试Spring管理的组件。
在这个例子中,JiSuanQiTest 类是一个JUnit测试类,它使用了这两个注解来配置Spring环境,以便能够测试 JiSuanQi 类的功能。

(3)测试结果

在这里插入图片描述

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

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

相关文章

前端面经-总结篇 http

下面是我在过去12天内&#xff0c;学习关于http的前端面经汇总。现在只是一些很基础的知识&#xff0c;后续还会补充&#xff0c;算是对之前学习的一个总结。 前端面经整理-CSDN博客 我主要参考的题目来源在这里。 本地存储 localstorage&#xff08;本地存储&#xff09;和…

功能篇:SpringBoot 实现静态、动态定时任务,本地动态定时任务调度

在Spring Boot中实现静态和动态定时任务可以通过使用Scheduled注解来配置静态的调度任务&#xff0c;以及通过编程方式创建动态的调度任务。下面我将分别介绍这两种方式。 ### 静态定时任务 对于静态定时任务&#xff0c;你可以直接在方法上使用Scheduled注解&#xff0c;并指定…

服务器ubuntu重装系统后将原来的用户进行关联

服务器ubuntu重装系统后将原来的用户数据进行关联 关联用户到已存在目录 sudo useradd user_name -m -s /bin/bash -d /home***/name添加sudo权限 vim /etc/sudoers# 文件末尾添加 user_name ALL(ALL:ALL) ALL更改拥有者 sudo chown -R user_name:user_name /home***/na…

数据地图怎么做?推荐这款数据可视化地图生成器

在数字化与信息化高速发展的今天&#xff0c;企业迎来了前所未有的发展机遇&#xff0c;规模迅速扩张&#xff0c;市场版图不断延伸。然而&#xff0c;伴随着这种快速的发展&#xff0c;一个不容忽视的问题逐渐浮出水面——如何精准高效地掌握分布在各地的分公司、业务点乃至整…

鸿蒙项目云捐助第九讲鸿蒙App应用的捐助详情页功能实现

鸿蒙项目云捐助第九讲鸿蒙App应用的捐助详情页功能实现 这里接下来继续实现捐助详情页的布局页面&#xff0c;也就是当用户进入到分类页面后&#xff0c;点击分类的每一个商品就进入到捐助商品的详情页&#xff0c;这里的布局可以从下面的模板演化而来。 下面根据这个模板来进…

docker mysql挂载

在提供的 docker run 命令中&#xff0c;已经挂载了三个卷到 MySQL 容器中&#xff1a;日志目录、数据目录和配置目录。然而&#xff0c;还没有挂载一个包含 cube_admin.sql 文件的目录。要将 SQL 文件放入容器中并在 MySQL 中执行它&#xff0c;可以按照以下步骤操作&#xff…

【数学】矩阵的逆与伪逆 EEGLAB

文章目录 前言matlab代码作用EEGLAB 中的代码总结参考文献 前言 在 EEGLAB 的使用中&#xff0c;运行程序时出现了矩阵接近奇异值&#xff0c;或者缩放错误。结果可能不准确。RCOND 1.873732e-20 的 bug&#xff0c;调查 EEGLAB 后发现是 raw 数据的问题。 matlab代码 A_1 …

【蓝凌表单】JSP组件常用语法整理

JSP组件常用语法整理 必填非必填写法//必填 $("[name=extendDataFormInfo.value(fd_344677482769e2)]").attr("validate","requiredvalue"); //非必填 $(

Redis 数据备份与恢复

Redis 数据备份与恢复 1. 引言 Redis 作为一款高性能的键值数据库,被广泛应用于各种场景,如缓存、消息队列等。由于其重要性,对 Redis 数据进行定期备份是保证数据安全的关键措施。本文将详细介绍 Redis 数据的备份与恢复方法,确保在数据丢失或系统故障时能够迅速恢复。 …

音视频入门基础:MPEG2-TS专题(17)——FFmpeg源码中,解析TS program map section的实现

一、引言 由《音视频入门基础&#xff1a;MPEG2-TS专题&#xff08;16&#xff09;——PMT简介》可以知道&#xff0c;PMT表&#xff08;Program map table&#xff09;由一个或多个段&#xff08;Transport stream program map section&#xff0c;简称TS program map sectio…

华为HarmonyOS NEXT 原生应用开发:鸿蒙中组件的组件状态管理、组件通信 组件状态管理小案例(好友录)!

文章目录 组件状态管理一、State装饰器1. State装饰器的特点2. State装饰器的使用 二、Prop装饰器&#xff08;父子单向通信&#xff09;1. Prop装饰器的特点2. Prop装饰器的使用示例 三、Link装饰器&#xff08;父子双向通信&#xff09;1. Link装饰器的特点3. Link使用示例 四…

Pytorch | 对比Pytorch中的十种优化器:基于CIFAR10上的ResNet分类器

Pytorch | 对比Pytorch中的十种优化器&#xff1a;基于CIFAR10上的ResNet分类器 CIFAR10数据集ResNet提出背景网络结构特点工作原理优势 代码实现分析utils.pymain.py导入必要的库设备选择与数据预处理定义加载训练集和测试集主函数部分训练部分测试部分 结果10种优化器对应的训…

Linux系统操作03|chmod、vim

上文&#xff1a; Linux系统操作02|基本命令-CSDN博客 目录 六、chmod&#xff1a;给文件设置权限 1、字母法 2、数字法&#xff08;用的最多&#xff09; 七、vim&#xff1a;代码编写和文本编辑 1、启动和退出 1️⃣启动 2️⃣退出 2、vim基本操作 六、chmod&#x…

【漏洞复现】eking管理易Html5Upload接口存在任意文件上传漏洞

🏘️个人主页: 点燃银河尽头的篝火(●’◡’●) 如果文章有帮到你的话记得点赞👍+收藏💗支持一下哦 【漏洞复现】eking管理易Html5Upload接口存在任意文件上传漏洞 一、漏洞概述1.1漏洞简介1.2组件描述1.3漏洞描述二、漏洞复现2.1 应用协议2.2 环境搭建2.3 漏洞复现三、…

徐州数字孪生工业互联网可视化技术,赋能新型工业化智能制造工厂

#徐州数字孪生工业互联网#在当下智能制造的热潮之下&#xff0c;徐州作为中国制造业的重要基地&#xff0c;正积极拥抱数字化转型&#xff0c;通过数字孪生工业互联网可视化技术&#xff0c;赋能新型工业化智能制造工厂&#xff0c;引领制造业向更高效、更智能、更绿色的方向发…

C# 探险之旅:第二十四节 - 类型class基础,一场“类”似的奇妙冒险

嘿&#xff0c;勇敢的探险家们&#xff01;欢迎来到C#王国的“类”似奇妙冒险&#xff01;今天&#xff0c;我们要深入探索一个神秘而强大的领域——class&#xff08;类&#xff09;。想象一下&#xff0c;class就像C#世界里的一块魔法土地&#xff0c;每块土地上都能孕育出独…

解决MyBatis在 Oracle 中使用 IN 语句不能超过 1000 问题

在 Oracle 数据库中&#xff0c;IN 语句常用于查询某个字段是否属于一组特定的值。对于大多数开发者而言&#xff0c;IN 是一种简单直观的查询方式&#xff0c;能够提升开发效率&#xff0c;避免过多的 OR 语句。然而&#xff0c;许多人在使用 IN 语句时可能遇到一个问题&#…

(五)机器学习 - 数据分布

数据分布&#xff08;Data Distribution&#xff09;是指数据在不同值或值区间内的分布情况&#xff0c;它描述了数据点在整个数据集中是如何分散或集中的。数据分布可以通过多种方式来分析和表示&#xff0c;包括图形和数值方法。 常见的数据分布特征和描述数据分布的方法&…

C# 探险之旅:第二十三节 - 字符(char):字符小精灵的独舞

嘿&#xff0c;探险家们&#xff01;欢迎再次踏上C#王国的奇妙旅程。这一节里&#xff0c;我们要深入探索一个非常基础但又极其重要的角色——字符(char)。想象一下&#xff0c;你正在参加一场由单个字母和数字组成的精灵舞会&#xff0c;每个精灵都代表着一个独特的字符。让我…

【JAVA】Java项目实战—分布式微服务项目:分布式文件存储系统

Java分布式微服务项目&#xff1a;分布式文件存储系统 一、背景介绍 随着互联网的快速发展和用户数据量的激增&#xff0c;软件开发中&#xff0c;传统的单体应用架构逐渐无法满足高并发、高可用和可扩展的需求。微服务架构应运而生&#xff0c;它将一个大型应用拆分为多个小…