【第五章 AOP概述,底层原理,AOP术语,切入点表达式,AOP操作(基于注解方式,基于xml配置文件)】

news2024/10/2 10:26:18

第五章 AOP概述,底层原理,AOP术语,切入点表达式,AOP操作(基于注解方式,基于xml配置文件)

1.AOP概述:
(1)什么是AOP:
①面向切面编程(方面),利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分间的耦合度降低,提高程序的可重用性,同时提高开发的效率。
②通俗描述:不通过修改源代码方式,在主干功能里面添加新功能。
(2)底层原理:
①AOP底层使用动态代理:有两种情况动态代理。
第一种,有接口情况:使用jdk动态代理;
创建接口实现类代理对象,增强类的方法。
第二种,没有接口情况,使用CGLIB动态代理。
创建子类的代理对象,增强类的方法。
②AOP(jdk动态代理):
a.使用jdk动态代理,使用Proxy类里面的方法创建代理对象。

调用newProxyInstance方法
方法有三个参数:
第一个参数:类加载器。
第二个参数:增强方法所在类,这个类实现的接口,支持多个接口。
第三个参数:实现这个接口InvocationHandler,创建代理对象,写增强的方法。

b.编写jdk动态代理代码。
第一步:创建接口,定义方法;

public interface UserDao {
    public int add(int a,int b);
    public String update(String id);
}

第二步:创建接口实现类,实现方法;

public class UserDaoImpl implements UserDao {
    @Override
    public int add(int a, int b) {
        System.out.println("add方法执行了");
        return a+b;
    }
    @Override
    public String update(String id) {
        System.out.println("update方法执行了");
        return id;
    }
}

第三步:使用Proxy类创建接口代理对象;

public class JDKProxy {
    public static void main(String[] args) {
        //创建接口实现类代理对象
        Class[] interfaces={UserDao.class};
        UserDaoImpl userDao=new UserDaoImpl();
        UserDao dao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao));
        int result = dao.add(1, 2);
        System.out.println("result"+result);
    }
}
//创建代理对象代码
class UserDaoProxy implements  InvocationHandler{
    //把创建的是谁的代理对象,把谁传递过来
    //有参数的构造进行传递
    private  Object obj;
    public UserDaoProxy( Object obj){
        this.obj=obj;
    }
    //增强的逻辑
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //方法之前
        System.out.println("方法之前执行"+method.getName()+":传递参数--->"+ Arrays.toString(args));
        //被增强的方法执行
        Object res = method.invoke(obj, args);
        //方法之后
        System.out.println("在方法之后执行"+obj);
        return res;
    }
}

(3)AOP术语:
①连接点:类里面哪些方法可以被增强,这些方法称为连接点。
②切入点:实际被真正增强的方法,称为切入点。
③通知(增强):实际增强的逻辑部分称为通知(增强)
通知有多种类型:前置通知、后置通知、环绕通知、异常通知、最终通知(类似于try-catch中的finally)
④切面:把通知应用到切入点的过程。
2.AOP操作(准备工作):
(1)在spring框架中一般基于AspectJ实现AOP操作。
AspectJ:不是spring组成部分,独立AOP框架,一般把AspectJ和spring框架一起使用,进行AOP操作。
(2)基于AspectJ实现AOP操作。
①基于xml配置文件实现;
②基于注解方式实现。
(3)在项目中引入AOP依赖:
在这里插入图片描述(4)切入点表达式:
①切入点表达式作用:知道要对哪个类里面的哪个方法进行增强。
②语法结构:

execution([权限修饰符] [返回类型] [类全路径名] [方法名称] [参数列表])
举例1:对demo1.dao.BookDao类里面的add进行增强
execution(* demo1.dao.BookDao.add(..))
举例2:对demo1.dao.BookDao类里面的所有方法进行增强
execution(* demo1.dao.BookDao.*(..))
举例3:对demo1.dao.包里面的所有类,类里面的所有方法进行增强
execution(* demo1.dao.*.*(..))

3.AOP操作(AspectJ 基于注解方式)
(1)创建类,在类里面定义方法;

//被增强类
public class User {
    public void add(){
        System.out.println("add......");
    }
}

(2)创建增强类,编写增强逻辑
①在增强类里面,创建方法,让不同的方法代表不同通知类型。

//增强类
public class UserProxy {
    //前置通知
    public void  before(){
        System.out.println("before....");
    }
}

(3)进行通知的配置
①在spring配置文件中,开启注解的扫描

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
        <!--开启注解扫描-->
    <context:component-scan base-package="aopano"></context:component-scan>

②使用注解创建User和UserProxy对象

@Component
public class User {}
@Component
public class UserProxy {}

③在增强类上面添加注解@Aspect

@Component
@Aspect
public class UserProxy {}

④在spring配置文件中开启生成代理对象

   <!--开启Aspect生成代理对象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

(4)配置不同类型的通知
①在增强类里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置

//增强类
@Component
@Aspect
public class UserProxy {
    //前置通知
    @Before(value = "execution(* aopano.User.add(..))")
    public void  before(){
        System.out.println("before....");
    }
}
测试的时候执行的是被增强的方法
 @Test
    public void testAopno(){
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean2.xml");
        User user = applicationContext.getBean("user", User.class);
        user.add();
    }

在这里插入图片描述

	//前置通知
    @Before(value = "execution(* aopano.User.add(..))")
    public void  before(){
        System.out.println("before....");
    }
    //最终通知
    @After(value = "execution(* aopano.User.add(..))")
    public void  after(){
        System.out.println("after....");
    }
    //后置通知
    @AfterReturning(value = "execution(* aopano.User.add(..))")
    public void  afterReturning(){
        System.out.println("afterReturning....");
    }
    //异常通知
    @AfterThrowing(value = "execution(* aopano.User.add(..))")
    public void  afterThrowing(){
        System.out.println("afterThrowing....");
    }
    //环绕通知
    @Around(value = "execution(* aopano.User.add(..))")
    public void  around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕之前");
        //被增强的方法执行
        proceedingJoinPoint.proceed();
        System.out.println("环绕之后");
    }

在这里插入图片描述(5)公共切入点进行抽取:

 //相同切入点进行抽取
    @Pointcut(value = "execution(* aopano.User.add(..))")
    public void  pointdemo(){
    }
    //前置通知
    @Before(value = "pointdemo()")
    public void  before(){
        System.out.println("before....");
    }

(6)有多个增强类对同一个方法进行增强,设置增强类优先级。
在增强类的上面添加注解@Order(数字类型值),数字类型值越小,优先级越高。

@Component
@Aspect
@Order(1)
public class personProxy {
    @Before(value = "execution(* aopano.User.add(..))")
    public void  afterReturning(){
        System.out.println("person before ....");
    }
}

4.AOP操作(AspectJ 基于xml配置文件方式)(了解)
(1)创建两个类,增强类和被增强类,创建方法;

public class Book {
    public void buy(){
        System.out.println("buy.....");
    }
}
public class BookProxy {
    public  void  before(){
        System.out.println("before....");
    }
}

(2)在spring配置文件中创建两个类对象;

     <!--创建两个类的对象-->
    <bean id="book" class="aopxml.Book"></bean>
    <bean id="bookProxy" class="aopxml.BookProxy"></bean>

(3)在spring配置文件中配置切入点。

	<!--aop的增强-->
    <aop:config >
        <!--切入点-->
        <aop:pointcut id="p" expression="execution(* aopxml.Book.buy(..))"/>
        <!--配置切面-->
        <aop:aspect ref="bookProxy">
            <!--增强作用在具体的方法上-->
            <aop:before method="before" pointcut-ref="p"></aop:before>
        </aop:aspect>
    </aop:config>

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

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

相关文章

11-KMP算法

KMP算法是一个字符串匹配算法&#xff0c;总的意义是在给定的字符串A中利用优化的方法快速地找出字符串B的位置&#xff0c;相比于传统匹配算法&#xff0c;它能有效减少匹配时间&#xff0c;提高效率。 前缀和后缀 在我们看KMP算法前我们先考虑一个问题&#xff1a;假如我们…

基于框架的平台总线式开发

一、总线、设备、驱动 硬编码式的驱动开发带来的问题&#xff1a; 1. 垃圾代码太多 2. 结构不清晰 3. 一些统一设备功能难以支持 4. 开发效率低下 1.1 初期解决思路&#xff1a;设备和驱动分离 struct device来表示一个具体设备&#xff0c;主要提供具体设备相关的资源&am…

Telnet 基础实验2: SSH 实验

Telnet 基础实验2&#xff1a; SSH 实验 本实验只能使用 eNSP中 AR 系统的路由器做 拓扑图 SSH &#xff1a; Secure Shell 是一个网络安全协议&#xff0c;基本于 TCP 协议 22 端口传输数据&#xff0c;通过对网络数据的加密&#xff0c;使其能够在一个不安全的网络环境中&a…

网易新财报:游戏养家,教育维稳、音乐快走

配图来自Canva可画 随着互联网流量红利逐渐消退&#xff0c;互联网大厂们也告别高增长时代&#xff0c;逐渐进入稳定增长阶段。近两年&#xff0c;流量焦虑、业务失速等问题更是成为了一团浓雾&#xff0c;笼罩在互联网大厂周围。不过&#xff0c;面对所遭遇的难题&#xff0c…

力扣-换座位

大家好&#xff0c;我是空空star&#xff0c;本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目&#xff1a;626. 换座位二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.其他总结前言 …

读书笔记——《富爸爸穷爸爸》

《富爸爸穷爸爸》&#xff0c;以前不屑读这种书。这种书就是那种走进书店放在门口展销位的成功学著作&#xff0c;一眼看上去没什么实在的内容&#xff0c;看上去很不靠谱&#xff0c;感觉就是骗一些社会底层又做着暴富梦的人来买的&#xff0c;但是由于自身原因或环境局限根本…

Spring Boot + Vue3 前后端分离 实战 wiki 知识库系统<二>---后端架构完善与接口开发

数据库准备&#xff1a; 在上一次Spring Boot Vue3 前后端分离 实战 wiki 知识库系统<一>---Spring Boot项目搭建已经将SpringBoot相关的配置环境给搭建好了&#xff0c;接下来则需要为咱们的项目创建一个数据库。 1、mysql的安装&#xff1a; 关于mysql的安装这里就…

【C语言每日一题】杨氏矩阵(源码以及改进源码)

【C语言每日一题】—— 杨氏矩阵&#x1f60e;&#x1f60e;&#x1f60e; 目录 &#x1f4a1;前言&#x1f31e;&#xff1a; &#x1f49b;杨氏矩阵题目&#x1f49b; &#x1f4aa; 解题思路的分享&#x1f4aa; &#x1f60a;题目源码的分享&#x1f60a; &#x1f4…

夜天之书 #73 Apache Pulsar 的社群指标

去年十一月&#xff0c;我成为了 Apache Pulsar[1] 社群 Committers 的一员。成为 Committer 之前和之后&#xff0c;我都积极参与了代码仓库上 Issue 和 Pull Request (PR) 的处理回应和评审。去年十二月期间&#xff0c;我把未解决的 Issue 和 PR 数量分别从接近 2000 个和 4…

STM32学习笔记-I2C通信协议

文章目录介绍&#xff1a;两种实现方式&#xff1a;I2C设备的常用连接方式&#xff1a;I2C协议时序&#xff1a;STM32硬件I2C框架图I2C外设通讯过程**I2C读写EEPROM**&#xff08;硬件I2C&#xff09;介绍&#xff1a; 两根通信线SCL&#xff08;时钟线&#xff09;、SDA&#…

C语言中的强制类型转换

强制类型转换是把变量从一种类型转换为另一种数据类型。例如&#xff0c;如果您想存储一个 long 类型的值到一个简单的整型中&#xff0c;您需要把 long 类型强制转换为 int 类型。您可以使用强制类型转换运算符来把值显式地从一种类型转换为另一种类型&#xff0c;如下所示&am…

“ChatGPT之父”Sam Altman:如何成功?

背靠微软&#xff0c;OpenAI能拳打谷歌&#xff0c;脚踢Meta&#xff0c;它背后的男人&#xff0c;必然不简单。 让我们来看一看&#xff0c;Sam Altman是如何一步步成长为今天这个搅动全世界的男人。 山姆奥特曼&#xff08;Sam Altman&#xff09; 成长和创业经历 在YC创始…

代码随想录【Day27】| 39. 组合总和、40. 组合总和 II、131. 分割回文串

39. 组合总和 题目链接 题目描述&#xff1a; 给定一个无重复元素的数组 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的数字可以无限制重复被选取。 说明&#xff1a; 所有数字&#xff08;包括 tar…

JavaScript 高级2 :构造函数和原型 d331702016e84f54b3594ae05e0eeac

JavaScript 高级2 &#xff1a;构造函数和原型 Date: January 16, 2023 Text: 构造函数和原型、继承、ES5中的新增方法 目标 能够使用构造函数创建对象 能够说出原型的作用 能够说出访问对象成员的规则 能够使用 ES5新增的一些方法 构造函数和原型 概述 在典型的 OOP 的…

MySQL之EXPLAIN

使用方法 查询结果分析 id&#xff1a;识别符 select_type&#xff1a;表示查询的类型 table&#xff1a;输出结果集的表 partitions&#xff1a;匹配的分区 type&#xff1a;表示表的连接类型 possible_keys&#xff1a;表示查询时&#xff0c;可能使用的索引 key&#xff1a…

jni-Demo-基于linux(c++ java)

跑一个jni 的最简单的Demo需要提前准备 VsCode 编译器、win10下&#xff0c;vscode中集成linux操作系统、c编译器&#xff08;gcc、g&#xff09;&#xff0c;java编译器&#xff08;jdk1.8&#xff09;参考&#xff1a;https://mangocool.com/1653030123842.htmlJniDemo类&…

【分享】灌溉制度设计小程序VB源代码

说明 根据作物需水特性和当地气候、土壤、农业技术及灌水技术等因素制定的灌水方案。主要内容包括灌水次数、灌水时间、灌水定额和灌溉定额。灌溉制度是规划、设计灌溉工程和进行灌区运行管理的基本资料&#xff0c;是编制和执行灌区用水计划的重要依据。 1—计划湿润土层允…

spring面试题总结

1、spring是什么&#xff1f; spring是一个轻量级IOC和AOP容器框架&#xff0c;是为Java应用程序提供基础性服务的一套框架&#xff0c;目的是用于简化企业应用的开发&#xff0c;开发者只需要关注业务需求即可&#xff1a; core container 容器组件 spring context&#xff0c…

@ConfigurationProperties在方法上的使用

文章目录1. 前言2. 先说结论3. 代码解释1. Component ConfigurationProperties2. EnableConfigurationProperties ConfigurationProperties3. Bean ConfigurationProperties1. 前言 在学习spring的时候&#xff0c;ConfigurationProperties应该经常被使用到&#xff0c;作用…

一文弄清混合云架构模式

当我们在说云架构的时候&#xff0c;通常指的并不是云平台的自身架构&#xff0c;而是基于云平台的软件系统基础架构。云平台的自身架构满足了很多通用层面的需求&#xff0c;例如对象存储&#xff0c;弹性主机&#xff0c;虚拟网络等等&#xff0c;只有云服务厂商的工程师才会…