【Spring】AOP原来如此

news2025/1/17 16:43:18

AOP概述

什么是AOP的技术?

  • 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程
  • AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构
  • AOP最早由AOP联盟的组织提出的,制定了一套规范.Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范
  • 通过预编译方式或者运行期动态代理实现程序功能的统一维护的一种技术
  • AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型
  • 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率

AOP:面向切面编程.(思想.---解决OOP遇到一些问题)

        AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)

为什么要学习AOP,可以在不修改源代码的前提下,对程序进行增强!!


说到增强你觉得AOP和谁比较像? 没错是代理 ,不了解看这篇文章00=》【javaSE】代理并不难-CSDN博客


AOP的底层原 理

JDK的动态代理技术

​ 1、为接口创建代理类的字节码文件

​ 2、使用ClassLoader将字节码文件加载到JVM

​ 3、创建代理类实例对象,执行对象的目标方法

cglib代理技术

1、创建拦截器:继承MethodInterceptor的 intercepter的类,在拦截器中重写intercerpt( )方法,就是增强+目标对象的方法调用,返回拦截器

2、在测试这边创建一个类似proxy的子类对象enhancer,然后设置这个代理对象的类型(setSuperclass(目标对象的类型.class完成))

3、创建一个拦截器,enhancer通过去设置回调函数(setCallback(拦截器))

4、创建代理对象enhancer.create(),代理对象的类型要和目标对象一致哈,然后通过代理对象去完成方法的调用


 AOP相关的术语

  • Joinpoint(连接点) 所谓连接点是指那些被拦截到的点。在spring,这些点指的是方法,因为spring只支持方法类型的连接点
  • Pointcut(切入点) -- 所谓切入点是指我们要对哪些Joinpoint进行拦截的定义
  • Advice(通知/增强)-- 所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)
  • Target(目标对象)-- 代理的目标对象
  • Weaving(织入)-- 是指把增强应用到目标对象来创建新的代理对象的过程
  • Proxy(代理)-- 一个类被AOP织入增强后,就产生一个结果代理类
  • Aspect(切面)-- 是切入点和通知的结合,以后咱们自己来编写和配置的

基于代理类的AOP

Spring的AOP代理默认用的就是JDK代理方式来实现的,在Spring中,ProxyFactoryBean是创建AOP代理的最基本方法(不常用,后面有更好的方法)

ProxyFactoryBean

ProxyFactoryBean是FactoryBean接口的实现类,FactoryBean负责实例化一个Bean,而ProxyFactoryBean负责为其他Bean创建代理实例。

ProxtFactoryBean类的常用配置属性

target

代理的目标对象

proxyInterfaces

代理要实现的接口,如果有多个接口,可以使用一些形式赋值

...

proxyTargetClass

是否对类代理而不是接口,设置为true时,使用CGLIB代理

interceptorNames

需要织入目标的Advice

singleton

返回的代理是否为单实例,默认为true

optimize

设置为true,强制使用CGLIB

下面是一个典型例子:

导包

在核心jar包基础上导入AOP的jar包,

  • Spring-aop-4.3.6.RELEASE.jar
  • aopalliance-1.0.jar
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>aopalliance</groupId>
    <artifactId>aopalliance</artifactId>
    <version>1.0</version>
</dependency>

编写配置类 

package com.aqiuo.factorybean;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
//切面类。实现了MethodInterceptor方法拦截器接口
public class MyAscpect implements MethodInterceptor{

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
            
        check_permissions();
        Object object= mi.proceed();
        log();
        return object;
    }
    //增强的方法体--通知
    public void check_permissions() {
        System.out.println("模拟权限检查");
    }
//增强的方法体--通知
    public void log() {
        System.out.println("模拟日志记录");
    }

}

 编写配置文件

//application.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd 
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd " > 
          
           <!-- 目标类 用的是jdk的对象 -->
    <bean id="accountService" class="com.aqiuo.service.impl.AccountServiceImpl"></bean>
    <!-- 切面类 -->
    <bean id="myAspect" class="com.aqiuo.aspect.MyAspect02"></bean>

    <!-- 使用Spring工厂定义一个名称为userDaoProxy的代理对象 -->
    <bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 指定代理要实现的接口 -->
        <property name="proxyInterfaces" value="com.aqiuo.service.AccountService"></property>
        <!-- 指定目标对象 -->
        <property name="target" ref="accountService"></property>
        <!-- 指定切面,执行环绕通知 -->
        <property name="interceptorNames" value="myAspect"></property>
        <!-- 指定代理方式 -->
        <property name="proxyTargetClass" value="true"></property>
    </bean>
       
   
</beans>


//测试

强调:获取的对象是代理之后的对象,不是原来的目标对象,获取原来的目标对象是不会有增强的 

    @Test
    public void run2() throws SQLException {
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService accountService= (AccountService) applicationContext.getBean("userDaoProxy");

        accountService.pay(100,1,2);

    }

在上述代码中,首先通过bean元素定义了目标类和切面,然后使用ProxyFactoryBean类定义了代理对象。

        在定义的代理对象中,分别通过子元素指定了代理实现的接口、代理的对象、需要织入的目标类的通知,已经代理方式


 下篇文章讲解AOP的AspectJ,AspectJ是一个居于JAVA开发的AOP框架》》框架

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

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

相关文章

如何在VSCode搭建ESP-IDF开发ESP32

文章目录 概要安装VScode安装ESP-IDF插件使用官方例程小结 概要 ESP-IDF(Espressif IoT Development Framework) 即乐鑫物联网开发框架&#xff0c;它基于 C/C 语言提供了一个自给自足的 SDK&#xff0c;可为在 Windows、Linux 和 macOS 系统平台上开发 ESP32 应用程序提供工具…

【单片机项目实战】温度控制系统

本项目的主要作用是实现温度调控&#xff0c;通过设定一个预定的温度值&#xff0c;实现实时检测外界温度&#xff0c;当外界温度小于预定值时&#xff0c;电机正转&#xff0c;实现降温效果&#xff1b;当外界温度大于预定值时&#xff0c;电机反转&#xff0c;实现升温效果&a…

神秘的Cookie和Session

Cookie 1.Cookie是什么&#xff1f; Cookie是浏览器提供的持久化储存数据的方式。 2.从哪里来&#xff1f; Cookie从服务器中来&#xff0c;存储到客户端中。一个客户端就对应着一个浏览器。 服务器代码中决定了什么样的数据会储存到客户端中&#xff0c;通过HTTP相应的Se…

C# WPF上位机开发(以始为终,寻找真实的上位机需求)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 c# wpf、qt、mfc这些上位机的需求是真实存在的&#xff0c;在现实中有很多应用的地方&#xff0c;这一点大家都很清楚。而程序员本身呢&#xff0c…

0101包冲突导致安装docker失败-docker-云原生

文章目录 1 前言2 报错3 解决结语 1 前言 最近在学习k8s&#xff0c;前置条件就是要安装指定版本的docker&#xff0c;命令如下 yum install -y docker-ce-20.10.7 docker-ce-cli-20.10.7 containerd.io-1.4.62 报错 file /usr/libexec/docker/cli-plugins/docker-buildx fr…

企业网盘的价值与用途:一篇文章带您了解核心功能与优势

企业网盘是当下企业管理中热度高居不下的话题&#xff0c;那么企业网盘到底是什么&#xff1f;企业网盘有什么用&#xff1f; 企业网盘是什么&#xff1f; 企业网盘是基于云计算理念推出的企业数据网络存储和管理解决方案&#xff0c;通俗来讲&#xff0c;企业网盘就是一个企…

算法基础day1

归并排序模版 #include <iostream> using namespace std; int n; const int N 1e610; int q[N],tmp[N]; void merge_sort(int l,int r,int q[]){if(l>r) return;int mid lr>>1;merge_sort(l,mid,q);merge_sort(mid1,r,q);//归并的的过程int k0,il,jmid1;while(…

MAC 中多显示器的设置(Parallels Desktop)

目录 一、硬件列表&#xff1a; 二、线路连接&#xff1a; 三、软件设置&#xff1a; 1. 设置显示器排列位置及显示参数 2. 分别设置外接显示器为&#xff1a;扩展显示器&#xff0c;内建显示器为主显示器 3. 设置Parallels Desktop屏幕参数 四、结果 一、硬件列表&a…

小白学 PyTorch 系列:54个超强 pytorch 操作

最近观察到一个有趣的趋势&#xff0c;越来越多的人在学术界热衷于学习和应用PyTorch。在工业界&#xff0c;虽然仍有一些项目在延续使用之前的深度学习框架&#xff0c;但 PyTorch 的影响力也在逐渐渗透。 对于昨天为什么没发文&#xff0c;原因很心酸。把 PyTorch 的这篇文章…

亚马逊云科技Amazon Q,一款基于生成式人工智能的新型助手

近日&#xff0c;亚马逊云科技宣布推出Amazon Q&#xff0c;这是一款基于生成式人工智能&#xff08;AI&#xff09;的新型助手&#xff0c;专为辅助工作而设计&#xff0c;可以根据您的业务量身定制。通过连接到公司的信息存储库、代码、数据和企业系统&#xff0c;可以使用Am…

Vue2中使用echarts,并从后端获取数据同步

一、安装echarts npm install echarts -S 二、导入echarts 在script中导入&#xff0c;比如&#xff1a; import * as echarts from "echarts"; 三、查找要用的示例 比如柱状图 四、初始化并挂载 <template><div id"total-orders-chart" s…

归并算法排序

目录 归并排序 逆序对的数量 归并排序 题目如下&#xff1a; 给定你一个长度为 n 的整数数列。 请你使用归并排序对这个数列按照从小到大进行排序。 并将排好序的数列按顺序输出。 输入格式&#xff1a; 输入共两行&#xff0c;第一行包含整数 n。 第二行包含 n 个整数&…

CEC2017(Python):差分进化算法DE求解CEC2017

一、CEC2017简介 参考文献&#xff1a; [1]Awad, N. H., Ali, M. Z., Liang, J. J., Qu, B. Y., & Suganthan, P. N. (2016). “Problem definitions and evaluation criteria for the CEC2017 special session and competition on single objective real-parameter numer…

Android 实现 Slots 游戏旋转效果

文章目录 前言一、效果展示二、代码实现1.UI布局2.SlotAdapter2.SlotsActivity 总结 前言 slots游戏&#xff1a; Slots游戏是一种极具流行度的赌博和娱乐形式&#xff0c;通常被称为老虎机或水果机。它们在赌场、线上游戏平台和手机应用中广泛存在。一般这类游戏都使用Unity…

重温MySQL之索引那些事

文章目录 前言一、概念1.1 索引作用1.2 索引类型1.3 B树索引结构1.4 B树索引源码分析 二、查询计划2.1 explain2.2 id2.3 select_type2.4 table2.5 partitions2.6 type2.7 possible_keys2.8 key2.9 key_len2.10 ref2.11 rows2.12 filtered2.13 Extra 三、索引优化3.1 索引失效3…

【2023年终总结】 | 时光之舟:乘载着回忆与希望穿越2023,抵达2024

文章目录 1 回忆2 希望 1 回忆 2023年对我来说是非常梦幻的一年&#xff0c;我在2023年初的时候确认去做AI方向&#xff0c;在这之前我尝试了前端开发&#xff0c;移动App开发&#xff0c;云FPGA等方向&#xff0c;但是感觉自己都不是很喜欢&#xff0c;然后就开始尝试新的方向…

idea如何设置自动换行

idea设置自动换行其实很简单&#xff0c;只需要进行一步操作就可以了。   看下图&#xff1a;我们只需要在相应的位置加上文件的类型就可以了&#xff0c;比如我们写的类都是.java文件&#xff0c;那么我们只需要加上 *.java就可以实现自动换行了。

基于Springboot实现天天生鲜销售电商平台

SSM毕设分享 基于Springboot实现天天生鲜销售电商平台 1 项目简介 Hi&#xff0c;各位同学好&#xff0c;这里是郑师兄&#xff01; 今天向大家分享一个毕业设计项目作品【】 师兄根据实现的难度和等级对项目进行评分(最低0分&#xff0c;满分5分) 难度系数&#xff1a;3分 …

HarmonyOS4.0系统性深入开发11通过message事件刷新卡片内容

通过message事件刷新卡片内容 在卡片页面中可以通过postCardAction接口触发message事件拉起FormExtensionAbility&#xff0c;然后由FormExtensionAbility刷新卡片内容&#xff0c;下面是这种刷新方式的简单示例。 在卡片页面通过注册Button的onClick点击事件回调&#xff0c;…

【大数据面试知识点】Spark中的累加器

Spark累加器 累加器用来把Executor端变量信息聚合到Driver端&#xff0c;在driver程序中定义的变量&#xff0c;在Executor端的每个task都会得到这个变量的一份新的副本&#xff0c;每个task更新这些副本的值后&#xff0c;传回driver端进行merge。 累加器一般是放在行动算子…