【SSM】篇二:注解开发与AOP

news/2024/7/4 7:40:23

文章目录

  • 1、注解开发
    • 1.1 注解开发定义bean
    • 1.2 纯注解开发模式
    • 1.3 注解开发Bean的作用范围和生命周期
    • 1.4 注解开发依赖注入
    • 1.5 注解开发管理第三方Bean
  • 2、Spring整合案例
    • 2.1 Spring整合mybatis
    • 2.2 Spring整合Junit
  • 3、AOP
    • 3.1 AOP思想入门案例
    • 3.2 AOP工作流程
    • 3.3 AOP切入点表达式
    • 3.4 AOP的通知类型
    • 3.5 AOP通知获取数据

1、注解开发

1.1 注解开发定义bean

注解开发定义bean的步骤:

  • 使用@Component定义bean,括号中的字符串即之前bean的id属性(不写id也行,getBean的时候按类型获取)
    在这里插入图片描述
  • 核心配置文件appliacationContext.xml中通过组件扫描加载bean(此时上一章的bean标签定义的无用了,就可以注释掉了):
    在这里插入图片描述

如果以后注解定义开发bean的时候都用@Component,对于不同的场景用起来不够清楚易于区分,由此Spring提供@Component注解的三个衍生注解:

  • @Controller:用于表现层bean的定义
  • @Service:用于业务层bean的定义
  • @Repository:用于数据层bean的定义

1.2 纯注解开发模式

Spring3.0升级了纯注解开发模式,使用java类替代核心配置文件,开启Spring快速开发跑道。

在这里插入图片描述

  • @Configuration注解用于设定当前类为配置类
  • @ComponentScan注解用于设定扫描路径,此注解只能加一次,多个路径用数组
@ComponentScan({"com.llg","com.fight.Dao"});
  • 读取Spring核心配置文件来初始化容器对象改为Java配置类来初始化容器对象
    在这里插入图片描述

1.3 注解开发Bean的作用范围和生命周期

  • @Scope注解用来说明bean是否为单例
  • @PostConstruct和@PreDestroy注解即定义生命周期

在这里插入图片描述

运行效果:
在这里插入图片描述

PS:
这两个注解报错的时候,需要在pom文件中导入依赖:

    <dependency>
      <groupId>javax.annotation</groupId>
      <artifactId>javax.annotation-api</artifactId>
      <version>1.3.2</version>
    </dependency>

1.4 注解开发依赖注入

自动装配的注解@Autowired

使用自动装配的注解@Autowired,按类型注入:

在这里插入图片描述
定义要注入的bean:
在这里插入图片描述
运行:
在这里插入图片描述
当被注入的类型的bean不止一个的时候,仅用@Autowired注解就会报错NoUniqueBeanDefinitionException

在这里插入图片描述

限定符注解@Qualifier("xxx")

此时,再加限定符注解@Qualifier(“xxx”),输入要注解的bean的名称,指定名称装配bean,即可解决。

注意:

  • 自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法

使用@Value实现简单类型注入

使用@Value实现简单类型注入:

在这里插入图片描述

加载properties文件@PropertySource

上面直接在@Value注解后给属性赋一个定值,显然不符合解耦和之前的思想,考虑使用properties文件:

在这里插入图片描述
此时,@Value注解优化为使用${}去获取:

在这里插入图片描述

@PropertySource("classpath:jdbc.properties")

路径中的properties文件有多个的时候,使用数组的格式写入,且不允许使用通配符


1.5 注解开发管理第三方Bean

使用@Bean配置第三方bean

在这里插入图片描述

但如果每个对象都写到核心配置中,管理和可读性都很差,可抽成一个独立的配置类,再导入到核心配置中:

  • 独立配置类

在这里插入图片描述

  • 使用@Import注解将配置类导入到核心配置类中,这个注解只能用一次,多个时用数组
    在这里插入图片描述
  • 当然,除了上面的直接导入,也可以用之前的 @ComponentScan注解扫描配置类所在的包,加载对应的配置类信息 ,推荐使用@Import
    在这里插入图片描述

为第三方Bean注入资源

  • 第三方bean注入简单的数据类型–使用成员变量
    在这里插入图片描述
  • 注入引用类型,只需要为定义bean的方法设置一个对应类型的形参,容器会根据类型去自动装配对象
    在这里插入图片描述

XML配置和注解的对比:

在这里插入图片描述


2、Spring整合案例

2.1 Spring整合mybatis

2.2 Spring整合Junit

3、AOP

3.1 AOP思想入门案例

AOP,即Aspect Oriented Programming,面向切面编程。是一种编程范式,指导开发者如何组织程序结构。在不惊动原始设计的基础上为其进行功能增强,实现无侵入式编程。

回顾:
OOP(面向对象编程)
Object Oriented Programming


AOP思想举例:

在这里插入图片描述
核心概念:

在这里插入图片描述

入门案例:

思路分析:

  • 导入坐标(pom.xml)
  • 制作连接点方法(即原始的Dao接口和实现类)
  • 制作共性功能(通知类与通知)
  • 定义切入点
  • 绑定切入点与通知关系

1.导入坐标(pom.xml)
在这里插入图片描述

2.制作连接点方法(即原始的Dao接口和实现类)

在这里插入图片描述
3.制作共性功能(通知类与通知)

在这里插入图片描述

4.定义切入点
在这里插入图片描述
切入点的定义需要依托一个不具有实际意义的方法进行,如上面的pt()方法,它无参数、无返回值、方法体无实际逻辑。
其中:@Pointcut注解来定义切入点

5.绑定切入点与通知的关系,并指定通知添加到原始连接点具体执行位置
在这里插入图片描述
注意,需要用注解@Component定义通知类受Spring容器管理,再加注解@Aspect定义当前类为切面类,最后在Spring核心配置类中使用注解@EnableAspectJAutoProxy开启对AOP注解驱动支持

在这里插入图片描述
至此,在未改动原程序的基础上,update方法新增了功能–打印当前时间:

在这里插入图片描述

3.2 AOP工作流程

在这里插入图片描述
注意,若bean对应的类中的方法没有匹配到任意切入点,则创建出来的bean就是普通对象,无关AOP,也无关代理对象。

在这里插入图片描述
打印bean,由于toString被重写,看不出来区别,调用getClass方法,可以看到代理类class是com.sun.proxy.$Proxy19,整个AOP的实现就是使用了代理模式。


3.3 AOP切入点表达式

切入点表达式语法:

  • 切入点:需要进行增强的那个方法,如上面的update
  • 切入点表达式:即要进行增强的这个方法,怎么去描述它

比如描述要增强的update,可以按照接口,也可以按照它的实现类:

在这里插入图片描述

切入点表达式标准格式:
---->
动作关键词(访问修饰符 返回值 包名.类/接口名 .方法名(参数)异常名)
execution(public User com.llg.service.Uservice.findById(int))
  • 动作关键字:描述切入点的行为动作,execution即执行到指定切入点
  • 方法修饰符:public、private等可以省略
  • 返回值
  • 包名
  • 类/接口名
  • 参数
  • 异常名:方法定义中抛出指定异常,可以省略

通配符

使用通配符来描述切入点,提高效率:

  • *:单个独立的任意符号,可以独立出现,也可做为前缀或后缀匹配符。
execution(public * com.llg.*.UserService.find* (*))

匹配com.llg包下得任意包中得UserService类或接口中所有find开头得带有一个参数、返回类型任意的public方法

  • . .:多个连续的任意符号,可独立出现,常用于简化包名与参数的书写
execution(public User com..UserService.findById(..))

匹配com包下的任意包中的UserService类或接口中所有名称为findById的方法

  • +:专门用于匹配子类类型
execution(* *..*Service+.*(..))

切入点表达式的书写技巧:

在这里插入图片描述

3.4 AOP的通知类型

AOP通知描述了抽取的共性功能,根据共性功能抽取的位置的不同,最终代码运行时要将其加入到合理的位置中,这个位置,有5中类型:

  • 前置通知
  • 后置通知
  • 环绕通知
  • 返回后通知
  • 抛出异常后通知

代码实现:


各个类型的详解:

@Before:
在这里插入图片描述
@After
在这里插入图片描述
@Around
在这里插入图片描述
注意:pjp.proceed()是对原始操作的调用,这样就区分出来了环绕具体是怎么个执行顺序,当原始操作有返回值的时候,这里要改为Object类型,并接收proceed方法的返回值来return。(原始操作返回void,也可以使用Object类型,这时候返回的是null而已)

在这里插入图片描述
@AfterReturning
在这里插入图片描述
@AfterThrowing
在这里插入图片描述



案例--测量业务层接口万次执行效率

计算时间差即执行时长,需要在接口执行前后分别记录时间==>环绕通知
在这里插入图片描述
使用环绕通知,先实现执行时长:
在这里插入图片描述

通过执行签名信息,来获取所测的接口名和方法名:
在这里插入图片描述

3.5 AOP通知获取数据

在这里插入图片描述

获取切入点方法的参数:

在这里插入图片描述

获取切入点方法返回值
  • 对于AfterReturning,我们使用形参来接收返回值:
    在这里插入图片描述
  • 对于Around,执行原始方法时,得到的结果即返回值:
    在这里插入图片描述
获取切入点方法异常信息
  • 对于Around,不再throw,直接try…catch即可:
    在这里插入图片描述
  • 对于AfterThrowing,使用新参接收异常对象:
    在这里插入图片描述


案例:百度网盘密码数据兼容处理

实现核心:使用环绕通知对原始操作的参数进行修改
在这里插入图片描述
代码实现:

业务层接口和实现类:
在这里插入图片描述在这里插入图片描述
数据层接口和实现类:
在这里插入图片描述
在这里插入图片描述
使用AOP思想,为业务层方法,加上去空格的功能,提高兼容性和用户使用体验:
在这里插入图片描述
测试程序:

在这里插入图片描述
运行结果:
在这里插入图片描述

====================

AOP总结:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


http://lihuaxi.xjx100.cn/news/955271.html

相关文章

每日统计部门人员考勤打卡情况并汇总通知

在值班时&#xff0c;HR需要及时了解到部分人员的打卡情况。这个时候&#xff0c;可以通过腾讯云HiFlow来实现自动通知考勤打卡情况。实现步骤&#xff1a;Step1&#xff1a;我们进入腾讯云HiFlow官网&#xff0c;进入控制台。我们在触发应用选择【定时启动-每天】触发。这里我…

SWM181按键控制双通道PWM固定占空比输出

SWM181按键控制双通道PWM固定占空比输出&#x1f4cc;SDK固件包&#xff1a;https://www.synwit.cn/kuhanshu_amp_licheng/ &#x1f33c;开发板如下图&#xff1a; ✨注意新手谨慎选择作为入门单片机学习。目前只有一个简易的数据手册和SDK包&#xff0c;又没有参考手册&am…

如何使用固态继电器实现更高可靠性的隔离和更小的解决方案尺寸

自晶体管发明之前&#xff0c;继电器就已被用作开关。从低压信号安全控制高压系统的能力&#xff0c;如隔离电阻监控&#xff0c;对于许多汽车系统的开发是必要的。虽然机电继电器和接触器的技术多年来有所改进&#xff0c;但设计人员要实现其终身可靠性和快速开关速度以及低噪…

软考论文-成本管理(1)

成本管理 1.成本管理的主要内容&#xff1f; 规划成本&#xff1a;制定一个成本管理的计划。估算成本&#xff1a;根据项目范围说明书&#xff0c;项目管理计划和wbs等文档&#xff0c;采用xxx方法进行估算成本成本预算&#xff1a;可以算工作包的费用&#xff0c;制定预算和…

Ubuntu 18.04 LTS 和 CentOS 7 增加 Swap 空间

注意&#xff1a;随着时间的流逝&#xff0c;其中的信息可能已经有所发展或是发生改变。侵删&#xff01; 文章目录前言环境&#xff1a;使用文件划分swap 分区删除之前的swap文件&#xff08;如果有&#xff09;创建一个swap文件配置为开机自动启用swap 的使用策略前言 由于我…

burp联动xray进行被动扫描

burp联动xray进行被动扫描0、简介1、打开burp&#xff0c;设置转发数据包&#xff0c;将burp抓到的数据包&#xff0c;额外转发到本机的7777端口2、出现这个代表配置成功3、接着在xray里输入这串代码&#xff0c;让xray进行监听本机的7777端口&#xff0c;进行被动扫描&#xf…

用Python自己写一个分词器,python实现分词功能,隐马尔科夫模型预测问题之维特比算法(Viterbi Algorithm)的Python实现

☕️ 本文系列文章汇总&#xff1a; &#xff08;1&#xff09;HMM开篇&#xff1a;基本概念和几个要素 &#xff08;2&#xff09;HMM计算问题&#xff1a;前后向算法 代码实现 &#xff08;3&#xff09;HMM学习问题&#xff1a;Baum-Welch算法 代码实现&#xff08…

树状数组讲解

树状数组 文章目录树状数组引入例题AcWing241.楼兰图腾思路代码AcWing 242. 一个简单的整数问题思路代码AcWing 244. 谜一样的牛思路代码总结引入 树状数组主要维护的是这样一个数据结构&#xff1a; tr[x]表示以x为终点的长度为lowbit(x)的前缀和 对于树状数组主要就两种操作 …