AOP实现方式-P20,21,22

news/2024/5/18 11:55:49/文章来源:https://blog.csdn.net/m0_54842832/article/details/127994455

 项目的包:

 pom依赖导入有关aop的包:

    <dependencies><!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version></dependency></dependencies>

代理类交给spring来实现。


UserService:

package com.Li.service;public interface UserService {public void add();public void delete();public void update();public void select();
}

UserServiceImpl:

package com.Li.service;public class UserServiceImpl implements UserService{@Overridepublic void add() {System.out.println("增加了一个用户!");}@Overridepublic void delete() {System.out.println("删除了一个用户!");}@Overridepublic void update() {System.out.println("修改了一个用户!");}@Overridepublic void select() {System.out.println("查询了一个用户!");}
}

log:

package com.Li.log;import org.springframework.aop.MethodBeforeAdvice;import java.lang.reflect.Method;
//前置日志
public class log implements MethodBeforeAdvice {//method: 要执行的目标对象的方法//args:参数//target:目标对象@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {System.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了");}
}

AfterLog:

package com.Li.log;import org.springframework.aop.AfterReturningAdvice;import java.lang.reflect.Method;
//后置日志
public class AfterLog implements AfterReturningAdvice {//returnValue: 返回值.由于是AfterReturning,所以有返回值@Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {System.out.println("执行了"+method.getName()+"方法,返回结果为:"+returnValue);}
}

方式一:(使用spring的接口实现动态代理类)

applicationContext.xml:

<?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:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!--注册bean--><bean id="userService" class="com.Li.service.UserServiceImpl"/><bean id="log" class="com.Li.log.log"/><bean id="afterLog" class="com.Li.log.AfterLog"/><!--方式一:使用原生Spring API接口--><!--配置aop:需要导入aop的约束--><aop:config><!--切入点:expression:表达式,execution(要执行的位置!)在那个类下区执行pointcut,就是用表达式定位。.*表示该类下的所有方法--><aop:pointcut id="pointcut" expression="execution(* com.Li.service.UserServiceImpl.*(..))"/><!--执行环绕增加!将log切入类切入到id为pointcut里将afterLog切入类切入到id为pointcut里--><aop:advisor advice-ref="log" pointcut-ref="pointcut"/><aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/></aop:config></beans>

MyTest:(测试)(不变)

import com.Li.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class MyTest {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");//动态代理代理的是接口:注意点UserService userService = context.getBean("userService", UserService.class);userService.add();}
}


方式二(主要是切面定义)

增加一个类:

DiyPointCut:

package com.Li.diy;public class DiyPointCut {public void before(){System.out.println("=====方法执行前=====");}public void after(){System.out.println("=====方法执行后=====");}}

applicationContext.xml:(看方式二)

<?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:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!--注册bean--><bean id="userService" class="com.Li.service.UserServiceImpl"/><bean id="log" class="com.Li.log.log"/><bean id="afterLog" class="com.Li.log.AfterLog"/><!--方式一:使用原生Spring API接口--><!--配置aop:需要导入aop的约束--><!--<aop:config>--><!--    &lt;!&ndash;切入点:expression:表达式,execution(要执行的位置!)在那个类下区执行pointcut,就是用表达式定位。.*表示该类下的所有方法&ndash;&gt;--><!--    <aop:pointcut id="pointcut" expression="execution(* com.Li.service.UserServiceImpl.*(..))"/>--><!--    &lt;!&ndash;执行环绕增加!--><!--        将log切入类切入到id为pointcut里--><!--        将afterLog切入类切入到id为pointcut里--><!--    &ndash;&gt;--><!--    <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>--><!--    <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>--><!--</aop:config>--><!--方式二:自定义类--><bean id="diy" class="com.Li.diy.DiyPointCut"/><aop:config><!--自定义切面,ref 要引用的类--><!--切面,就是类--><aop:aspect ref="diy"><!--切入点--><aop:pointcut id="point" expression="execution(* com.Li.service.UserServiceImpl.*(..))"/><!--通知(就是方法)--><aop:before method="before" pointcut-ref="point"/><aop:after method="after" pointcut-ref="point"/></aop:aspect></aop:config></beans>

测试(代码不变直接测试):

 


利用注解开发:

 

AnnotationPointCut:

package com.Li.diy;//方式三:使用注解方式实现AOPimport org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;@Aspect//标记这个类是一个切面
public class AnnotationPointCut {@Before("execution(* com.Li.service.UserServiceImpl.*(..))")public void before(){System.out.println("=====方法执行前=====");}@After("execution(* com.Li.service.UserServiceImpl.*(..))")public void after(){System.out.println("=====方法执行后=====");}}

 applicationContext.xml:

    <!--方式三--><bean id="annotationPointCut" class="com.Li.diy.AnnotationPointCut"/><!--开启注解支持--><aop:aspectj-autoproxy/>

直接测试

 

三种方式都可以实现AOP。第一种全面,第二种便于理解,第三种方便。你可以自己选择自己喜欢的方式。

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

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

相关文章

mysql-6-主从复制搭建

1 总结 1&#xff1a;主从复制最大缺陷就是延迟。 2 搭建前的准备 2.1复制的基本原则 每个slave只有一个master每个slave只能有一个唯一的服务器ID每个master可以有多个slavemysql版本尽量一致&#xff0c;防止出问题。两台服务能ping通MySQL主从是基于binlog的&#xff0c;主上…

【路径规划】(1) Dijkstra 算法求解最短路,附python完整代码

好久不见&#xff0c;我又回来了&#xff0c;这段时间把路径规划的一系列算法整理一下&#xff0c;感兴趣的点个关注。今天介绍一下机器人路径规划算法中最基础的 Dijkstra 算法&#xff0c;文末有 python 完整代码&#xff0c;那我们开始吧。 1. 算法介绍 1959 年&#xff0c…

FAIRNESS IN MACHINE LEARNING: A SURVEY 阅读笔记

论文链接 刚读完一篇关于机器学习领域研究公平性的综述&#xff0c;这篇综述想必与其有许多共通之处&#xff0c;重合部分不再整理笔记&#xff0c;可详见上一篇论文的笔记&#xff1a; A Survey on Bias and Fairness in Machine Learning 阅读笔记_Catherine_he_ye的博客 S…

scrapy的入门使用

目录 一、 安装scrapy 1.windonws/Mac安装命令&#xff1a; 2. 安装依赖包&#xff1a;pip install pypiwin32 二、 scrapy项目开发流程 1.创建项目:    2.生成一个爬虫: 3.提取数据: 4.保存数据: 三、 创建项目 四、创建爬虫 五、完善爬虫 5.2 定位元素以及提取…

浅识vue的虚拟DOM和渲染器

虚拟DOM本质上是对DOM的抽象描述&#xff0c;就是一个普通的js对象。他身上的属性要比真实DOM的属性要少得多。 在一定情况下&#xff0c;使用虚拟DOM的性能要逊于直接使用真实DOM。 例如&#xff0c;在页面一开始的时候&#xff0c;Vue需要先通过生成虚拟DOM树&#xff0c;在…

【面试】揭秘面试背后的那点真实

注&#xff1a;最后有面试挑战&#xff0c;看看自己掌握了吗 文章目录前言/背景面试流程资料总结/刷题指南个人经验总结寄语&#x1f338;I could be bounded in a nutshell and count myself a king of infinite space. 特别鸣谢&#xff1a;木芯工作室 、Ivan from Russia 金…

QT:debug日志—打不开头文件以及qDebug和Q_CLASSINFO的使用

这个是因为链接器在给定路径上搜索不到对应的头文件&#xff0c;而大多数的Qt相关的头文件都集中在一个include文件夹里&#xff1a; 我电脑上的路径是&#xff1a;C:\Qt\Qt5.9.7\5.9.7\msvc2017_64\include 然后我们在项目设置里&#xff1a; 注意&#xff0c;这边要加上\*&…

计算机系统基础期末复习

C语言代码如下&#xff1a; void fun(int n){ int x n*12;int y n/32; }请将其中计算的部分优化为位运算、移位运算和加法运算的结合。 x n8n4 (n<<3)(n<<2) x (n(n>>31) & 0x1F)>>5 设32位的位串为x(x类型为unsigned int)&#xff0c;现要…

Flink常用Sink(elasticsearch(es)Sink、RedisSink、KafkaSink、MysqlSink、FileSink)

flink输出到es、redis、mysql、kafka、file 文章目录配置pom文件公共实体类KafkaSInkElasticsearchSink(EsSink)RedisSinkMysqlSink(JdbcSink)FileSink自己先准备一下相关环境 配置pom文件 <properties><maven.compiler.source>8</maven.compiler.source>&l…

测试用例设计方法之场景设计法

基本流&#xff1a;采用直黑线表示&#xff0c;是经过用例的最简单的路径&#xff08;无任何差错&#xff0c;程序从开始直接执行到结束&#xff09; 备选流&#xff1a;采用不同颜色表示&#xff0c;一个备选流可能从基本流开始&#xff0c;在某个特定条件下执行&#xff0c;…

HTTP介绍报文格式构造

HTTP 一. 简单介绍一下: 二. 学习报文格式: 三. HTTP中的细节介绍 四, 如何构造一个HTTP请求 一. 简单介绍一下: 是应用层的典型协议客户端发送一个HTTP请求, 服务器返回一个HTTP响应(一问(请求)一答(响应)的)HTTP是文本格式的协议二. 学习报文格式: 1)先简单看一看HTTP的…

在CentOS 7.7 x86_64上为python 2.7.5安装pip的靠谱方法

我的虚拟机是CentOS 7.7 x86_64系统&#xff0c;对应的python默认版本是2.7.5&#xff0c;但是没有安装pip&#xff0c;不方便安装第三方模块。 我想为为它安装pip工具&#xff0c;发现现有的安装方法都行不通了&#xff0c;比如先安装easy_install&#xff0c;再通过easy_inst…

Nginx (4):nginx动静分离

什么是动静分离不解释了&#xff0c;网上说的很清楚&#xff0c;这里只说配置 目的 02虚拟机运行一个tomcat&#xff0c;处理动态请求&#xff0c;而对静态文件的访问则交给01虚拟机。操作 下面是01虚拟机的配置文件内容&#xff1a; server {listen 82;listen [::]:82;#root /…

pytorch案例代码-3

双向循环神经网络 双向循环神经网络在RNN/LSTM/GRU里都有。比如RNN cell&#xff0c;只是把h0和x1传入做线性变换产生h1继续传入同一个cell做线性变换&#xff0c;线性变换的W和b共享&#xff0c;沿着这个方向就把所有隐层和最后的输出算出来了。 那么其中的每个结点&#xff0…

文华财经期货K线多周期画线技术,多重短线技术共振通道线指标公式——多周期主图自动画线

期货指标公式是通过数学逻辑角度计算而来&#xff0c;仅是期货分析环节中的一个辅助工具。期货市场具有不确定性和不可预测性的&#xff0c;请正常对待和使用指标公式! 期货指标公式信号本身就有滞后性&#xff0c;周期越大&#xff0c;滞后性越久。指标公式不是100%稳赚的工具…

18.4 嵌入式指针概念及范例、内存池改进版

一&#xff1a;嵌入式指针&#xff08;embedded pointer&#xff09; 1、嵌入式指针概念 一般应用在内存池相关的代码中&#xff0c;成功使用嵌入式指针有个前提条件&#xff1a;&#xff08;类A对象的sizeof必须不小于4字节&#xff09; 嵌入式指针工作原理&#xff1a;借用…

Word2Vec 实践

Word2Vec 实践 gensim库使用 这里的Word2Vec借助 gensim 库实现&#xff0c;首先安装pip install gensim3.8.3 from gensim.models.word2vec import Word2Vecmodel Word2Vec(sentencesNone, size100, alpha0.025, window5, min_count5,max_vocab_sizeNone, sample1e-3, …

2023年系统规划与设计管理师-第三章信息技术服务知识

一. 思维导图 二.IT 服务管理 (ITSM) 1. 什么是 IT 服务管理 (ITSM)&#xff1f; IT 服务管理 (ITSM) 包含一组策略和实践&#xff0c;这些策略和实践可用于为最终用户实施、交付和管理 IT 服务&#xff0c;以满足最终用户的既定需求和企业的既定目标。 在此定义中&#xff0…

cocos2dx创建工程并在androidstudio平台编译

本文主要是通过androidstudio进行编译运行cocos2dx工程。 前置条件&#xff1a; 1&#xff1a;androidstudio已经下载并安装。 2&#xff1a;cocos2dx已经下载并打开。 这里androidstudio使用2021.3.1版本&#xff0c;cocos2dx使用4.0版本。 第一步&#xff0c;首先安装py…

基于JavaWeb的药品进销存管理系统(JSP)

目 录 绪论 1 1.1 本课题的研究背景 1 1.2 国内外研究现状 1 1.3 本课题的主要工作 2 1.4 目的和意义 2 开发工具及技术 3 2.1 开发工具 3 2.1.1 MyEclipse 3 2.1.2 Tomcat 3 2.1.3 Mysql 3 2.2 开发技术 4 2.2.1 JSP 4 2.2.2 MyBatis 4 2.2.3 JavaScript 4 2.2.4 jQuery以及j…