Spring——AOP

news/2024/11/7 12:38:19/

Spring中的可插拔组件技术

在这里插入图片描述

Spring AOP

  • Spring AOP——Aspect Oriented Programming 面向切面编程
  • AOP 的做法是将通用的、与业务无关的功能抽象封装为切面层
  • 切面可配置在目标方法执行前后,做到即插即用

不修改源码对程序功能进行拓展

AoP的关键概念

Spring AoP 与AspectJ的关系

  • Eclipse AspectJ,一种基于Java平台的面向切面编程的语言
  • Spring AoP 使用AspectJWeaver 实现 类与方法匹配
  • Spring AOP 利用代理模式实现对象运行时功能拓展

几个重要概念
在这里插入图片描述

AOP配置过程

  1. 依赖AaspectJ
  2. 实现切面类和方法
  3. 配置Aspect Bean
  4. 定义PointCut
  5. 配置Aadvice

JoinPoint核心方法

注解说明
Object getTarget()获取IoC容器内目标对象
Signature getSignature()获取目标方法
Object[] getArgs()获取目标方法参数

PointCut 切点表达式

在这里插入图片描述

五种通知类型

在这里插入图片描述
xml配置如下:

 <aop:config><!-- pointcut 切点,使用excution表达式描述切面的作用范围--><!-- execution(public * com.imooc..*.*(..))表达式说明切面作用在com.imooc包下的所有类的所有方法上 --><aop:pointcut id="pointcut" expression="execution(public * com.imooc..*Service.*(..))"/><aop:aspect ref="methodAspect"><!-- before 通知,代表在目标方法之前运行methodAspect.printExecutionTime--><aop:before method="printExecutionTime" pointcut-ref="pointcut"/><aop:after-returning method="doAfterReturning" returning="ret" pointcut-ref="pointcut"/><aop:after method="doAfter" pointcut-ref="pointcut"/><aop:after-throwing method="doAfterThrowing" throwing="exception" pointcut-ref="pointcut"/></aop:aspect></aop:config>

利用AOP 进行方法性能筛查

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns="http://www.springframework.org/schema/beans"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="userDao" class="com.imooc.spring.aop.dao.UserDao"/><bean id="employeeDao" class="com.imooc.spring.aop.dao.EmployeeDao"/><bean id="userService" class="com.imooc.spring.aop.service.UserService"><property name="userDao" ref="userDao"/></bean><bean id="employeeService" class="com.imooc.spring.aop.service.EmployeeService"><property name="employeeDao" ref="employeeDao"/></bean><!--<bean id="methodAspect" class="com.imooc.spring.aop.aspect.MethodAspect"></bean><aop:config>&lt;!&ndash; pointcut 切点,使用excution表达式描述切面的作用范围&ndash;&gt;&lt;!&ndash; execution(public * com.imooc..*.*(..))表达式说明切面作用在com.imooc包下的所有类的所有方法上 &ndash;&gt;<aop:pointcut id="pointcut" expression="execution(public * com.imooc..*Service.*(..))"/><aop:aspect ref="methodAspect">&lt;!&ndash; before 通知,代表在目标方法之前运行methodAspect.printExecutionTime&ndash;&gt;<aop:before method="printExecutionTime" pointcut-ref="pointcut"/><aop:after-returning method="doAfterReturning" returning="ret" pointcut-ref="pointcut"/><aop:after method="doAfter" pointcut-ref="pointcut"/><aop:after-throwing method="doAfterThrowing" throwing="exception" pointcut-ref="pointcut"/></aop:aspect></aop:config>--><bean id="methodChecker" class="com.imooc.spring.aop.aspect.MethodChecker"/><aop:config><aop:pointcut id="pointcut" expression="execution(* com.imooc..*.*(..))"/><aop:aspect ref="methodChecker"><aop:around method="check" pointcut-ref="pointcut"/></aop:aspect></aop:config>
</beans>

methodChecker:

package com.imooc.spring.aop.aspect;import org.aspectj.lang.ProceedingJoinPoint;import java.text.SimpleDateFormat;
import java.util.Date;/*** todo {类简要说明}** @Author wangw* @Date 2022/12/1 22:59* @Version 1.0*/
public class MethodChecker {// proceedingJoinPoint是原有JoinPoint的升级,在原有功能基础上,还能控制目标方法是否执行public Object check(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {try {long startTime = System.currentTimeMillis();Object ret =  proceedingJoinPoint.proceed();long endTime = System.currentTimeMillis();long duration =endTime-startTime;if (duration>=1000){SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:MM:ss SSS");String className = proceedingJoinPoint.getTarget().getClass().getName();String methodName =proceedingJoinPoint.getSignature().getName();Object[] args =proceedingJoinPoint.getArgs();String now = sdf.format(new Date());System.out.println("======"+now+":"+className+"."+methodName+"."+"("+duration+")ms==============");}return ret;} catch (Throwable e) {throw e;}}
}

基于注解开发SpringAOP

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

Spring AOP 实现原理

  • Spring 基于代理模式实现动态功能拓展,包含两种形式
  • 目标类拥有接口,通过JDK动态代理实现功能拓展
  • 目标类没有接口,通过CGLib实现功能拓展

代理模式

  • 代理模式通过代理对象对原对象实现功能拓展

在这里插入图片描述

(静态代理 是指必须手动创建按代理类的代理模式使用方式)

JDK动态代理

    private Object targetObj;public ProxyInvocationHandle(Object targetObj){this.targetObj =targetObj;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("前置执行方法");Object ret = method.invoke(targetObj,args);System.out.println("后置方法");return ret;}public static void main(String[] args) {UserService userService  = new UserServiceImpl();ProxyInvocationHandle proxyInvocationHandle = new ProxyInvocationHandle(userService);UserService userServiceProxy = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(),userService.getClass().getInterfaces(),proxyInvocationHandle);userServiceProxy.createUser();EmployeeService employeeService =new EmployeeServiceImpl();ProxyInvocationHandle proxyInvocationHandleProxy = new ProxyInvocationHandle(employeeService);EmployeeService employeeServiceProxy = (EmployeeService) Proxy.newProxyInstance(employeeService.getClass().getClassLoader(),employeeService.getClass().getInterfaces(),proxyInvocationHandleProxy);employeeServiceProxy.say();}
public interface EmployeeService {public void createNewEmployee();
}
public class EmployeeServiceImpl implements EmployeeService{public void say() {System.out.println("hello");}
}

CGLib

使用代理时如果没有接口,则使用CGLib
在这里插入图片描述

AOP 底层就是使用动态代理实现的!!!


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

相关文章

现在的程序员真是越来越懒了,api 文档都懒得写!程序员:“api工具惯的”

为了让大家更能清楚了解 Api 相关往期内容&#xff0c;我写了一个阅读指引&#xff1a; 序号学习路径指引链接1Api -- 连接世界的 Super StarApi -- 连接世界的Super Star_不吃西红柿丶的博客-CSDN博客2软件吞噬世界&#xff0c;Api 快速入门到放弃软件吞噬世界&#xff0c;Ap…

在 Git Bash 中为 vim 设置 Dracula 配色

因为本人一直习惯了用 Jetbrains 家的产品&#xff0c;而且一直独钟 Dracula 配色&#xff0c;因此想要在 Git Bash 中为 vim 配一款 Dracula 配色。本博客将详细介绍如何为 vim 配置暗系主题 Dracula。 一、安装 Dracula 在 Dracula 的官网其实已经给出了关于如何在 vim 中配…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java线上学习系统8e88w

毕业设计说实话没有想象当中的那么难&#xff0c;导师也不会说刻意就让你毕设不通过&#xff0c;不让你毕业啥的&#xff0c;你只要不是太过于离谱的&#xff0c;都能通过的。首先你得要对你在大学期间所学到的哪方面比较熟悉&#xff0c;语言比如JAVA、PHP等这些&#xff0c;数…

node开发MongoDB

MongoDB mongoDB中文文档 数据库简介 数据库&#xff1a;持久化存储数据的仓库 分类&#xff1a; 关系型数据库&#xff1a;mysql、oracle、sql server、db2 非关系型数据库&#xff1a;mongodb、redis MongoDB简介 文档数据库&#xff0c;类似json结构&#xff0c;存储各种…

基于Intel Lake-UP3平台的超声设备方案设计,提供出色的图形和AI性能

超声系统要求 有效的超声系统可加快诊断速度&#xff0c;并帮助医生更快做出更有效的治疗决策。 为此&#xff0c;超声机器要求极高的处理性能和图形渲染效果以提高诊断准确性&#xff0c;并立即获取精确的图像。 类似地&#xff0c;还需要易于移动以适应不断变化的医疗场景和…

新编译原理的草稿

经典编译原理似乎已经够用了&#xff0c;为什么要研究新编译原理呢&#xff1f;在四型文法中&#xff0c;只实现了前两型&#xff0c;现在用的编译原理&#xff0c;仍然是“上下文无关文法”。沿着文法产生式替换的思路走下去&#xff0c;很艰难&#xff0c;不如另辟蹊径&#…

可以作为艺术作品欣赏的CT三维重建技术。

什么是CT三维重建技术&#xff1a;简而言之就是通过螺旋CT自带的计算机软件&#xff0c;对扫描获得的数据进行后处理&#xff0c;以达到辅助医生对病变和周围组织&#xff0c;及其与血管的关系进行分析和显示的目的&#xff0c;它极大地提高了影像诊断的直观性&#xff0c;准确…

【MyBatis源码分析】六、MyBatis Plugins(拦截器)

六、MyBatis Plugins(拦截器) 文章目录 六、MyBatis Plugins(拦截器)拦截器的基本开发Plugins机制详解Plugins开发技巧prepare()Invocation与MetaObject开发打印Sql语句的Plugins应用场景Plugins实战开发分页插件的开发乐观锁的开发需求:如果我们要获得MyBatis在执行过程中…