面向切面编程AOP

1.Spring的AOP简介

1.1什么是AOP

AOP为Aspect Oriented Programming的缩写,意思是面向切面编程,是通过预编译和运行期动态代理实现程序功能维护的一种技术

AOP是OOP(面向对象)的延续,利用AOP可以对业务逻辑的各部分进行隔离,从而降低业务逻辑之间的耦合度,提高程序的可重用性,同时提高开发效率

1.2.AOP的作用及优势

作用:在程序运行期间,在不修改源码的情况下对方法进行功能增强

优势:减少重复代码,提高开发效率,便于维护

1.3AOP底层实现

AOP底层是通过Spring提供的动态代理技术实现的,Spring通过动态代理技术动态动态的生成代理对象,代理对象方法执行时进行增强功能介入

1.4 AOP的动态代理技术

JDK代理:基于接口的动态代理技术

cglib代理:基于父类的动态代理技术

1.5JDK的动态代理

(1)目标接口

public interface TargetInterface {
    public void method();
}

 (2)目标类

public class Target implements TargetInterface {
    @Override
    public void method() {
        System.out.println("Target running....");
    }
}

 (3)动态代理代码

    Target target = new Target(); //创建目标对象
    //创建代理对象
    TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(target.getClass()
    .getClassLoader(),target.getClass().getInterfaces(),new InvocationHandler() {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) 
    throws Throwable {
        System.out.println("前置增强代码...");
        Object invoke = method.invoke(target, args);
        System.out.println("后置增强代码...");
        return invoke;
        }
    }
);

 (4)调用代理对象的方法测试

proxy.method();

 1.6 cglib

(1)目标类

public class Target {
    public void method() {
        System.out.println("Target running....");
    }
}

 (2) 动态代理代码

        Target target = new Target(); //创建目标对象
        Enhancer enhancer = new Enhancer(); //创建增强器
        enhancer.setSuperclass(Target.class); //设置父类
        enhancer.setCallback(new MethodInterceptor() { //设置回调
        @Override
        public Object intercept(Object o, Method method, Object[] objects, 
        MethodProxy methodProxy) throws Throwable {
        System.out.println("前置代码增强....");
        Object invoke = method.invoke(target, objects);
        System.out.println("后置代码增强....");
        return invoke;
        }
    });
Target proxy = (Target) enhancer.create(); //创建代理对象

(3) 调用代理对象的方法测试

proxy.method();

 

1.7 AOP相关概念

Spring的AOP实现底层就是对上面的动态代理的代码进行了封装,封装后我们只需要对需要关注的部分进行代码编写,并通过配置的方式完成指定的方法增强

Target(目标对象):代理的目标对象

Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类

Joinpoint(连接点):所谓连接点是指那些 被拦截到的点,在Spring中这些点指的是方法

Pointcut(切入点):所谓切入点是指我们要对那些Joinpoint进行拦截定义

Advice(通知/增强):所谓通知是指拦截到Joinpoint之后要做的事情就是通知

Aspect(切面):是切入点和通知的结合

Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程

2.基于XML的AOP开发

2.1 快速入门

(1)导入AOP相关坐标

<!--导入spring的context坐标,context依赖aop-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<!-- aspectj的织入 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency

 (2)创建目标接口和目标类

public interface TargetInterface {
    public void method();
}
public class Target implements TargetInterface {
    @Override
    public void method() {
        System.out.println("Target running....");
    }
}

 (3) 创建切面类(内部有增强方法)

public class MyAspect {
    //前置增强方法
    public void before(){
        System.out.println("前置代码增强.....");
    }
}

 (4)将目标类和切面类的对象创建权交给Spring

<!--配置目标类-->
<bean id="target" class="com.lin.aop.Target"></bean>
<!--配置切面类-->
<bean id="myAspect" class="com.lin.aop.MyAspect"></bean>

 (5)在applicationContext.xml中导入aop的命名空间

<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/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
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">

 在applicationContext.xml中配置织入关系

配置切点表达式和前置增强的织入关系

<aop:config>
    <!--引用myAspect的Bean为切面对象-->
    <aop:aspect ref="myAspect">
        <!--配置Target的method方法执行时要进行myAspect的before方法前置增强-->
        <aop:before method="before" pointcut="execution(public void 
        com.lin.aop.Target.method())"></aop:before>
    </aop:aspect>
</aop:config>

(6)测试代码

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class AopTest {
        @Autowired
        private TargetInterface target;
        @Test
        public void test1(){
        target.method();
    }
}

2.2 xml配置AOP详解

1.切点表达式的写法

execution([修饰符] 返回值类型 包名.类名.方法名(参数))

访问修饰符可以省略
返回值类型、包名、类名、方法名可以使用星号* 代表任意
包名与类名之间一个点 . 代表当前包下的类,两个点 .. 表示当前包及其子包下的类
  参数列表可以使用两个点 .. 表示任意个数,任意类型的参数列表
execution(public void com.lin.aop.Target.method())
execution(void com.lin.aop.Target.*(..))
execution(* com.lin.aop.*.*(..))
execution(* com.lin.aop..*.*(..))
execution(* *..*.*(..))
2.通知类型
<aop:通知类型 method=“切面类中方法名” pointcut=“切点表达式"></aop:通知类型>

 3.切点表达式的抽取

当多个增强切点表达式相同时,可以将切点表达式进行抽取,在增强中使用pointcut属性来抽取切点表达式

<aop:config>
    <!--引用myAspect的Bean为切面对象-->
    <aop:aspect ref="myAspect">
    <aop:pointcut id="myPointcut" expression="execution(*         com.lin.aop.*.*(..))"/>
    <aop:before method="before" pointcut-ref="myPointcut"></aop:before>
    </aop:aspect>
</aop:config

2.3要点

aop织入的配置

<aop:config>
    <aop:aspect ref=“切面类”>
        <aop:before method=“通知方法名称” pointcut=“切点表达式"></aop:before>
    </aop:aspect>
</aop:config>

3.基于AOP的注解开发

3.1快速入门

(1)创建接口和目标类

public interface TargetInterface {
    public void method();
}
public class Target implements TargetInterface {
    @Override
    public void method() {
        System.out.println("Target running....");
    }
}

(2)创建切面类

public class MyAspect {
    //前置增强方法
    public void before(){
        System.out.println("前置代码增强.....");
    }
}

(3)将目标类和切面类的对象创建权交给spring

@Component("target")
public class Target implements TargetInterface {
    @Override
    public void method() {
        System.out.println("Target running....");
    }
}
@Component("myAspect")
public class MyAspect {
    public void before(){
        System.out.println("前置代码增强.....");
    }
}

(4)在切面类中使用注解配置织入关系

@Component("myAspect")
@Aspect
public class MyAspect {
@Before("execution(* com.itheima.aop.*.*(..))")
public void before(){
        System.out.println("前置代码增强.....");
    }
}

(5)在配置文件中开启组件扫描和AOP的自动代理

<!--组件扫描-->
<context:component-scan base-package="com.itheima.aop"/>
<!--aop的自动代理-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

(6)测试代码

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
        @Autowired
        private TargetInterface target;
        @Test
    public void test1(){
        target.method();
    }
}

 3.2注解配置AOP详解

同 xml 配置 aop 一样,我们可以将切点表达式抽取。抽取方式是在切面内定义方法,在该方法上使用@Pointcut
注解定义切点表达式,然后在在增强注解中进行引用。具体如下:
@@Component("myAspect")
@Aspect
public class MyAspect {
    @Before("MyAspect.myPoint()")
    public void before(){
        System.out.println("前置代码增强.....");
    }
@Pointcut("execution(* com.itheima.aop.*.*(..))")
    public void myPoint(){}
}

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

要是早看到这篇文章,你起码少走3年弯路,20年老程序员的忠告

文章目录前言一、程序员的薪资是怎么样的&#xff1f;二、我现在的情况适合做程序员吗&#xff1f;三、大学期间到底应该学些什么&#xff1f;四、工作还是考研&#xff1f;五、总结前言 我是龙叔&#xff0c;一名工作了20多年的退休老程序员。 如果你在工作之前看到这篇文章…

初时STM32单片机

目录 一、单片机基本认知 二、STM系列单片机命名规则 三、标准库与HAL库区别 四、通用输入输出端口GPIO 五、推挽输出与开漏输出 六、复位和时钟控制&#xff08;RCC&#xff09; 七、时钟控制 八、中断和事件 九、定时器介绍 一、单片机基本认知 单片机和PC电脑相比…

【个人首测】百度文心一言 VS ChatGPT GPT-4

昨天我写了一篇文章GPT-4牛是牛&#xff0c;但这几天先别急,文中我测试了用GPT-4回答ChatGPT 3.5 和 Notion AI的问题&#xff0c;大家期待的图片输入也没有出现。 昨天下午百度发布了文心一言&#xff0c;对标ChatGPT&#xff0c;录屏无实机演示让百度股价暴跌。但是晚上百度就…

黑马c++----string容器笔记

3.string容器 3.1.1string基本概念 本质: string 是c风格的字符串,而string本质上是一个类 string和char*区别: char*是—个指针string是一个类&#xff0c;类内部封装了char*&#xff0c;管理这个字符串&#xff0c;是一个char*型的容器。 特点:string类内部封装了很多成员…

常用React Hooks大合集(二)

React Hooks useRef useRef返回一个ref对象&#xff0c;返回的ref对象再组件的整个生命周期保持不变。 最常用的ref是两种用法&#xff1a; 用法一&#xff1a;引入DOM&#xff08;或者组件&#xff0c;但是需要是class组件&#xff09;元素&#xff1b;用法二&#xff1a;保…

Python制作9行最简单音乐播放器?不,我不满足

人生苦短 我用python 好久不见啦~这次就来给大家整个大福利 ~ 源码资料电子书:点击此处跳转文末名片获取 最简单的9行代码音乐播放器如下&#xff1a; import time import pygamefile r歌曲路径 pygame.mixer.init() print(正在播放,file) track pygame.mixer.music.load(f…

Unreal Engine 网络系统(一):网络模型及网络视角下的Gameplay框架

个人学习记录&#xff0c;如有错误请及时联系我&#xff01;欢迎交流&#xff01; 1.客户端-服务器模型 服务器&#xff1a;有一个客户端担当游戏状态的主控者 作用&#xff1a;做出所有重要决定&#xff0c;保证公平性&#xff0c;包含所有主控状态&#xff0c;处理客户端连接…

Redis高级篇

文章目录面试题库redis有哪些用法&#xff1f;redis单线程时代性能依然很快的原因&#xff1f;主线程和IO线程怎么协作完成请求处理的BigKey&#xff08;重要&#xff09;什么算是BigKey&#xff1f;怎么发现BigKey&#xff1f;怎么删除bigkey&#xff1f;bigkey生产调优缓存双…

ElasticSearch快速入门详解(亲测好用,强烈推荐收藏)

3.快速入门 接下来快速看下elasticsearch的使用 3.1.概念 Elasticsearch虽然是一种NoSql库&#xff0c;但最终的目的是存储数据、检索数据。因此很多概念与MySQL类似的。 ES中的概念数据库概念说明索引库&#xff08;indices)数据库&#xff08;Database&#xff09;ES中可…

小菜鸟Python历险记:(第四集)

今天写的文章是记录我从零开始学习Python的全过程。在Python中函数是非常重要的&#xff0c;这里也可以称为方法。在前面分享的几篇文章中用到的方法有print(),str(),int().这些都是方法&#xff0c;而除了上面写的这几种内置方法以外&#xff0c;我们也可以自己在程序中自定义…

【C++】用手搓的红黑树手搓set和map

目录 一、set/map的底层结构 1、set/map的源码 2、利用模板区分set/map 3、利用仿函数控制比较大小 二、set/map的迭代器&#xff08;红黑树的迭代器&#xff09; 1、红黑树的begin、end迭代器 2、红黑树迭代器的operator 3、红黑树迭代器的operator-- 三、set的const…

设置Typora图床(Github)

PicGo&#xff0c;Github&#xff0c;Typora Nodejs下载&#xff1a; Node.js PicGo下载&#xff1a; GitHub - Molunerfinn/PicGo: A simple & beautiful tool for pictures uploading built by vue-cli-electron-builder 选择downloads或release. 然后进行安装。 Gith…

MongoDB【部署 01】mongodb最新版本6.0.5安装部署配置使用及mongodb-shell1.8.0安装使用(云盘分享安装文件)

云盘分享文件&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/11sbj1QgogYHPM4udwoB1rA 提取码&#xff1a;l2wz 1.mongodb简单介绍 MongoDB的 官网 内容还是挺丰富的。 是由 C语言编写的&#xff0c;是一个基于分布式文件存储的开源数据库系统。在高负载的情况下&…

数据库面试题——锁

了解数据库的锁吗&#xff1f; 锁是数据库系统区别于文件系统的一个关键特性&#xff0c;锁机制用于管理对共享资源的并发访问。 InnoDB下两种标准行级锁&#xff1a; 共享锁&#xff08;S Lock&#xff09;&#xff0c;允许事务读一行数据。 排他锁&#xff08;X Lock&…

ChatGPT没有API?OpenAI官方API带你起飞

目录ChatGPT没有API&#xff1f;OpenAI官方API带你起飞安装 OpenAI 的 API 库包装个函数包装个UIAPI 调不通怎么办&#xff1f;ChatGPT没有API&#xff1f;OpenAI官方API带你起飞 前段时间ChatGPT爆火&#xff0c;OpenAI 的 GPT API也被大家疯狂调用&#xff0c; 但其实这个AP…

『OPEN3D』1.6 Voxelization体素化

目录 1 从triangle meshes中创建体素 2 从点云中创建体素 3 体素包含测试&#xff08;Inclusion test&#xff09; 4 Voxel carving 在点云处理的内容中&#xff0c;简单介绍了open3d中对点云下采样使用了体素的操作&#xff0c;这里对体素化进行详细的介绍。 点云和三角面…

【服务器数据恢复】使用碎片拼接方法恢复SQL Server数据库的数据恢复案例

服务器数据恢复环境&#xff1a; 某公司一台DELL服务器&#xff0c;作为WEB服务器使用&#xff0c;安装的Windows Server操作系统&#xff0c;配置了SQL Server数据库&#xff1b; 采用了Xen Server虚拟化系统&#xff1b; 底层是通过raid卡&#xff0c;用4块STAT硬盘搭建的RAI…

debian部署docker(傻瓜式)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 debian10部署dockerdebian10部署docker&#xff08;傻瓜式&#xff09;一、准备工作二、**使用 APT 安装&#xff0c;注意要先配置apt网络源**1.配置网络源2.官方下载三、安装…

Tomcat部署及优化

目录 1.Tomcat概述 1.Tomcat的概念 2、Tomcat的核心组件 3.Java Servlet 的概念 4.JSP的概念 5.Tomcat中最顶层的容器------server 6.四个子容器的作用 7.Tomcat请求过程 2.Tomcat服务部署 1.Tomcat服务部署的步骤 2.实例操作&#xff1a;Tomcat服务部署 3.Tomcat 虚拟主机配置…

FPGA基于RIFFA实现PCIE采集ov5640图像传输,提供工程源码和QT上位机

目录1、前言2、RIFFA理论基础3、设计思路和架构4、vivado工程详解5、上板调试验证并演示6、福利&#xff1a;工程代码的获取1、前言 PCIE是目前速率很高的外部板卡与CPU通信的方案之一&#xff0c;广泛应用于电脑主板与外部板卡的通讯&#xff0c;PCIE协议极其复杂&#xff0c…
最新文章