Spring框架使用Api接口实现AOP的切面编程、两种方式的程序示例以及Java各数据类型及基本数据类型的默认值/最大值/最小值列表
一、Spring框架使用Api接口-继承类实现AOP的切面编程示例
要使用Spring框架AOP,除了要导入spring框架包外,还需要导入一个织入的包org.aspectj,具体maven依赖如下:
<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.1.10.RELEASE</version>
</dependency>
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.6.9</version></dependency>
注,本文最先发表于publish:September 29, 2020 -Tuesday,在后来发现此时的代码已经有问题了,依赖的包加载报错,aspectj的版本需要换一下,我这里换成1.9.9后正常。
然后我们编写几个类,一个是接口类ArticleInterface,二是这个接口的实现类Article,三是需要往这个实现类Article中切入的切面类:BeforeLog 和AfterLog 分别在方法执行起和末尾执行的方法。类的实现代码如下:
//接口类ArticleInterface
package proxy;public interface ArticleInterface {public void query(); public void add() ;public void edit() ;public void delete() ;
}//接口的实现类Article
package proxy;public class Article implements ArticleInterface{public void query() {System.out.println("获取了一篇文章"); }public void add() {System.out.println("添加了一篇文章");}public void edit() {System.out.println("修改了一篇文章");}public void delete() {System.out.println("删除了一篇文章");}
}//前置切面类
package proxy;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;public class BeforeLog implements MethodBeforeAdvice{//Method 目标对象的方法;Object:目标对象;target:目标对象public void before(Method method, Object[] args, Object target) throws Throwable {// TODO Auto-generated method stub//此方法内容在目标方法执行前会自动执行System.out.println("开始执行方法:" + target.getClass().getName() + "." + method.getName());}}//后置切面类
package proxy;import java.lang.reflect.Method;import org.springframework.aop.AfterReturningAdvice;public class AfterLog implements AfterReturningAdvice{public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {// TODO Auto-generated method stubSystem.out.println("执行方法完成:" + target.getClass().getName() + "." + method.getName() );}}
注意,前置切面类和后置切面类分别实现了MethodBeforeAdvice和AfterReturningAdvice接口,也正因此他们能切入方法进行执行。至于切入至哪个目标类的哪个方法执行,需要我们进入applicationContext.xml中进行aop配置。如上我们需要将这两个切面类BeforeLog和AfterLog加至Article执行。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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!-- 上方导入aop约束 --><aop:aspectj-autoproxy /><bean id="article" class="proxy.Article" /><bean id="beforelog" class="proxy.BeforeLog" /><bean id="afterlog" class="proxy.AfterLog" /><!-- 进行aop配置 --><aop:config><!-- 表示:Article.*(..) Article类的所有方法任意参数 --><aop:pointcut expression="execution(* proxy.Article.*(..))" id="logcut"/><aop:advisor advice-ref="beforelog" pointcut-ref="logcut"/><aop:advisor advice-ref="afterlog" pointcut-ref="logcut"/></aop:config></beans>
程序的运行结果如下:
//运行结果如下:
开始执行方法:proxy.Article.add
添加了一篇文章
执行方法完成:proxy.Article.add
二、Spring使用自定义类来实现AOP切面编程
上一篇文章 使用Sprint的API(即要添加的通知功能都实现于Spring的接口)实现了AOP切面编程,也可以使用自定义的类来实现,我们可以写一个独立的CLASS类和一些方法,然后通过在applicationContext IOC容器配置中自定义切面 ,在这个切面中自定义我们的切入点并ref相关的方法从而实现切面编程。同样我们编写一个interface Printers和Computer类,还有一个自定义的横切关注点(切面,即自定义类)。代码如下:
//interface
package aspect;public interface Printers {public void print();
}//interface的实现类
package aspect;public class Computer implements Printers{public void print() {System.out.println("打印机执行打印");}}//自定义的横切关注点类
package aspect;public class PrintReady {public void ready() {System.out.println("准备墨水和纸");}public void clear() {System.out.println("整理桌面");}}
如上,我们编写了一个计算类,其有打印的方法,而我们想在打印机执行打印前后添加点其它功能,比如打印执行前准备墨水和纸,打印后整理桌面。注意看我们的横切关注点类PrintReady没有继承任何的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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><aop:aspectj-autoproxy /><bean id="computer" class="aspect.Computer" /><bean id="printready" class="aspect.PrintReady" /><aop:config><!-- 自定义切面 --><aop:aspect ref="printready"><!-- 切点 --><aop:pointcut expression="execution(* aspect.Computer.*(..))" id="doprint"/><aop:before method="ready" pointcut-ref="doprint" /><aop:after method="clear" pointcut-ref="doprint"/></aop:aspect></aop:config>
</beans>
测试类User的代码及运行结果如下:
package com.kermit.dotest;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import aspect.Printers;public class User {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");Printers computer = (Printers)context.getBean("computer");computer.print();}
}
运行结果如下:
//运行结果
准备墨水和纸
打印机执行打印
整理桌面
三、后来使用Api接口实现AOP切面编程的补充测试记录
1. execution缺少括号不报错但是切面方法就是不执行的坑
在测试的时候发现有一个坑,aplicationContext.xml配置文件中,如果expression里面少了一个括号,程序执行并不报错,但是就是不会执行AOP切面方法,如下请注意 代码 expression="execution(* com.kermit.aoptest.Article.*(..)"/> 中少了一个右括号,程序不报错,导致排查时一直未发现,还以为是哪里加载出现了问题。
<bean id="beforelog" class="com.kermit.aoptest.BeforeLog" /><bean id="afterlog" class="com.kermit.aoptest.AfterLog" /><aop:config><aop:pointcut id="logcut" expression="execution(* com.kermit.aoptest.Article.*(..)"/><aop:advisor advice-ref="beforelog" pointcut-ref="logcut"/><aop:advisor advice-ref="afterlog" pointcut-ref="logcut" /></aop:config>
2. 使用Spring的API接口实现AOP编程有两种方式
文章1是一种实现方式,其是将要切入的类方法都继承自 Spring的类方法 org.springframework.aop.MethodBeforeAdvice;和org.springframework.aop.AfterReturningAdvice; 还有一种方式是使用自定义类,先自己配置一个类实现方法前和方法后要切入的方法,然后加入切面中。
被切入的类内容如下:
package com.kermit.aoptest;import org.springframework.stereotype.Component;import java.sql.SQLOutput;
@Component
public class Article implements ArticleInterface{@Overridepublic void insert() {System.out.println("insert one record.");}@Overridepublic void update() {System.out.println("update one record.");}
}
自定义要切入的方法内容类定义如下:
package com.kermit.aoptest;public class DiyLog {public void before(){System.out.println("do before method");}public void after(){System.out.println("do after method");}
}
然后在配置文件中使用如下配置:
<bean id="diylog" class="com.kermit.aoptest.DiyLog" /><aop:config><aop:aspect ref="diylog"><aop:pointcut id="logcut" expression="execution(* com.kermit.aoptest.Article.*(..))"/><aop:before method="before" pointcut-ref="logcut"/><aop:after method="after" pointcut-ref="logcut"/></aop:aspect></aop:config>-->
这种方法与第1种方法相比,其的局限性比较大,因为其切入的只能是一些独立的方法内容,功能受限。
四、Java各数据类型的默认值/最大值/最小值
以前保存的 Java获取数据类型及基本数据类型的默认值、最大值、最小值保存在这里。
1. Java取各数据类型的认值/最大值/最小值的程序
//Java获取变量的数据类型及基本数据类型的默认值、最大最小值
package data.type;
public class Array {static boolean bool;static byte by;static char ch;static double dv;static float fv;static int iv;static long lv;static short shv;static String strv;public static void main(String[] args) {//Java中的基本数据类型System.out.println("------------各数据类型定义------------");byte b = 2; showType(b);short s = 3;showType(s);int i =10; showType(i);long l =19; showType(l);float f=1.3f;showType(f);double d=0.5;showType(d);char c ='a';showType(c);boolean bo = true; showType(bo);//Java 基本数据类型的默认值System.out.println("---------各类型默认值-------------");System.out.println("Bool :" + bool);System.out.println("Byte :" + by);System.out.println("Character:" + ch);System.out.println("Double :" + dv);System.out.println("Float :" + fv);System.out.println("Integer :" + iv);System.out.println("Long :" + lv);System.out.println("Short :" + shv);System.out.println("String :" + strv);//Java 基本数据类型的信息System.out.println("---------各类型信息-------------");System.out.println("byte类型字节数:"+ Byte.BYTES + ",最小值:" + Byte.MIN_VALUE + ",最大值"+Byte.MAX_VALUE);System.out.println("short类型字节数:"+ Short.BYTES + ",最小值:" + Short.MIN_VALUE + ",最大值"+Short.MAX_VALUE);System.out.println("int类型字节数:"+ Integer.BYTES + ",最小值:" + Integer.MIN_VALUE + ",最大值"+Integer.MAX_VALUE);System.out.println("long类型字节数:"+ Long.BYTES + ",最小值:" + Long.MIN_VALUE + ",最大值"+Long.MAX_VALUE);System.out.println("float类型字节数:"+ Float.BYTES + ",最小值:" + Float.MIN_VALUE + ",最大值"+Float.MAX_VALUE);System.out.println("double类型字节数:"+ Double.BYTES + ",最小值:" + Double.MIN_VALUE + ",最大值"+Double.MAX_VALUE);System.out.println("char类型字节数:"+ Character.BYTES + ",最小值:" + (int)Character.MIN_VALUE + ",最大值"+ (int)Character.MAX_VALUE);}public static void showType(Object obj) {System.out.println(obj.getClass().getTypeName() );}
}
2. Java取各数据类型的认值/最大值/最小值的程序运行结果:
------------各数据类型定义------------
java.lang.Byte
java.lang.Short
java.lang.Integer
java.lang.Long
java.lang.Float
java.lang.Double
java.lang.Character
java.lang.Boolean
---------各类型默认值-------------
Bool :false
Byte :0
Character:
Double :0.0
Float :0.0
Integer :0
Long :0
Short :0
String :null
---------各类型信息-------------
byte类型字节数:1,最小值:-128,最大值127
short类型字节数:2,最小值:-32768,最大值32767
int类型字节数:4,最小值:-2147483648,最大值2147483647
long类型字节数:8,最小值:-9223372036854775808,最大值9223372036854775807
float类型字节数:4,最小值:1.4E-45,最大值3.4028235E38
double类型字节数:8,最小值:4.9E-324,最大值1.7976931348623157E308
char类型字节数:2,最小值:0,最大值65535
相关文章:

Spring框架使用Api接口实现AOP的切面编程、两种方式的程序示例以及Java各数据类型及基本数据类型的默认值/最大值/最小值列表
一、Spring框架使用Api接口-继承类实现AOP的切面编程示例 要使用Spring框架AOP,除了要导入spring框架包外,还需要导入一个织入的包org.aspectj,具体maven依赖如下: <dependency><groupId>org.springframework</gr…...

【达梦数据库】尽可能 disql 的使用效果与异构数据库一致
文章目录 前言disql 效果优化参数设置参数说明 mysql参数设置参数说明 db2参数设置参数说明 待补充 前言 让达梦的disql 使用起来更跟手,与其他优质数据库的命令行工具通过配置参数的方式尽可能一致,提高使用体验,长期整理中~~~ 测试版本&…...

【研1深度学习】《神经网络和深度学习》阅读笔记(记录中......
9.27 语义鸿沟: 是指输入数据的底层特征和高层语义信息之间的不一致性和查一下。如果可以有一个好的表示在某种程度上能够反映出数据的高层语义特征,那么我们就能相对容易的构建后续的机器学习模型。嵌入(Embedding):…...

十一不停歇-学习ROS2第一天 (10.2 10:45)
话题通信 1.1 发布第一个节点: import rclpy #导入此类模块 rcl类型 from rclpy.node import Node #从这个子模块中导入这类函数 def main(): #定义这个函数 rclpy.init() #使用初始化函数 node Node(hello_python) 将类函数里面的内容调给…...

Java高效编程(14):考虑实现 `Comparable
解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 与其他方法不同,compareTo 并非 Object 类中声明的,而是 Comparable 接口的唯一方法。compareTo 方法与 equals 类似,但它不仅支持相等性比较,还允许顺序…...

华为昇腾CANN训练营2024第二季--Ascend C算子开发能力认证(中级)题目和经验分享
大家好,我是刘明,明志科技创始人,华为昇思MindSpore布道师。 技术上主攻前端开发、鸿蒙开发和AI算法研究。 努力为大家带来持续的技术分享,如果你也喜欢我的文章,就点个关注吧 正文开始 华为昇腾CANN训练营2024第二季…...

实战OpenCV之形态学操作
基础入门 形态学操作是一种基于图像形状的处理方法,主要用于结构分析,比如:边缘检测、轮廓提取、噪声去除等。这些操作通常使用一个称为“结构元素”(Structuring Element)的核来进行,结构元素可以是任何形状,但最常见的有矩形和圆形。形态学操作的核心在于通过结构元素…...

矩阵的特征值和特征向量
矩阵的特征值和特征向量是线性代数中非常重要的概念,用于描述矩阵对向量的作用,特别是在矩阵对向量的线性变换中的表现。它们帮助我们理解矩阵在某些方向上的缩放或旋转效果。 1. 特征值和特征向量的定义: 给定一个 n n n \times n nn 的…...

(11)MATLAB莱斯(Rician)衰落信道仿真2
文章目录 前言一、莱斯衰落信道仿真模型二、仿真代码与结果1.仿真代码2.仿真结果画图 三、后续:四、参考文献: 前言 首先给出莱斯衰落信道仿真模型,该模型由直射路径分量和反射路径分量组成,其中反射路径分量由瑞利衰落信道模型构…...

ComfyUI局部重绘换衣讲解
一、下载插件 ComfyUI-Impact-Pack 下载地址 https://github.com/ltdrdata/ComfyUI-Impact-Pack 主要用到sam Detector去绘制衣服蒙版和高斯模糊蒙版,高斯模糊让蒙版边缘更加柔和 sams模型 放在E:\Comfyui\ComfyUI\models\sams二、换衣思路 文生图或直接上传…...

Android——添加联系人
概述 方式一:使用ContentResolver多次写入,每次写入一个字段 第一步 往手机联系人应用中的raw_contacts表添加一条记录 raw_contacts表 ContentValues values new ContentValues();// 往 raw_contacts 添加联系人记录,并获取添加后的联…...

高级 Java Redis 客户端 有哪些?
高级Java Redis客户端主要包括以下几种: 1. Redisson (https://github.com/redisson/redisson) 特点:Redisson是一个在Redis的基础上实现的Java驻留数据网格(In-Memory Data Grid)。它不仅是一个Redis的J…...

jenkins项目发布基础
随着软件开发需求及复杂度的不断提高,团队开发成员之间如何更好地协同工作以确保软件开发的质量已经慢慢成为开发过程中不可回避的问题。Jenkins 自动化部署可以解决集成、测试、部署等重复性的工作,工具集成的效率明显高于人工操作;并且持续集成可以更早的获取代码变更的信息,…...

前缀和算法详解
对于查询区间和的问题,可以预处理出来一个前缀和数组 dp,数组中存储的是从下标 0 的位置到当前位置的区间和,这样只需要通过前缀和数组就可以快速的求出指定区间的和了,例如求 l ~ r 区间的和,就可以之间使用 dp[l - 1…...

Android-Handle消息传递和线程通信
本文为作者学习笔记,如有误,请各位大佬指点 目录 一、同步异步 二、Java多线程通信 三、Handler是什么 四、Handler相关的类 五、Handler常用方法 1. 发送消息 2. 接收处理消息 3. 切换线程 六、使用Handler 使用Handler更新UI 使用Handler延…...

【Kubernetes】常见面试题汇总(四十七)
目录 106.考虑一种情况,公司希望通过保持最低成本来提高效率和技术运营速度。您如何看待公司将如何实现这一目标? 107.假设一家公司想要修改其部署方法,并希望构建一个可扩展性和响应性更高的平台。您如何看待这家公司能够实现这一目标以满足…...

grafana全家桶-loki promtail收集k8s容器日志
loki是grafana旗下轻量级日志收集工具,为了减少loki对集群的影响,把loki的agent日志收集端promtail部署在k8s集群中,loki server部署在集群外面。这样简单做一个解耦,避免大量读写的应用影响到集群内业务服务。 一、promtail部署…...

HTML5+CSS+JavaScript剪子石头布游戏
HTML5CSSJavaScript剪子石头布游戏 用HTML5CSSJavaScript剪子石头布游戏实现剪子石头布游戏,游戏有成绩计数,人、机输赢情况,及平局情况。 ✂代表剪刀,▉代表石头,▓ 代表布,给出人机双方的出拳情况 游戏…...

Flask-3
文章目录 ORMFlask-SQLAlchemySQLAlchemy中的session对象数据库连接设置常用的SQLAlchemy字段类型常用的SQLAlchemy列约束选项 数据库基本操作模型类定义 数据表操作创建和删除表 数据操作基本查询SQLAlchemy常用的查询过滤器SQLAlchemy常用的查询结果方法多条件查询分页器聚合…...

Redis的基本使用
简介 传统的数据库是 关系数据库,但是Redis是键值对数据库传统的数据库是基于 磁盘存储的,但是Redis是基于 内存存储的 基于内存,读写性能更高内存是不大的,只能存储热点信息 安装 绿色软件,安装即可使用 安装服务 手…...

[241004] Linux 系统中配置文件的区别 | VirtualBox 7.1.2 发布,修复多项问题并提升性能
目录 Linux 系统中 /etc/profile, ~/.bash_profile, ~/.profile, ~/.bashrc 等配置文件的区别一、配置文件类型二、配置文件作用三、交互式登录 Shell 和非登录 Shell交互式登录 shell交互式非登录 shell 四、配置文件加载顺序五、~/.bash_profile 和 ~/.bashrc 的区别 Virtual…...

hbuilderx+uniapp+Android宠物用品商城领养服务系统的设计与实现 微信小程序沙箱支付
目录 项目介绍支持以下技术栈:具体实现截图HBuilderXuniappmysql数据库与主流编程语言java类核心代码部分展示登录的业务流程的顺序是:数据库设计性能分析操作可行性技术可行性系统安全性数据完整性软件测试详细视频演示源码获取方式 项目介绍 顾客 领养…...

SVN 迁移到 GIT,并保留提交记录
1)svn账号与git账号映射 创建 user.txt ,格式如下,user.txt 放置在git base here 所选目录下即可 schacon Scott Chacon <schacongeemail.com> selse Someo Nelse <selsegeemail.com> 为了获得 SVN 使用的作者名字列表…...

【数据结构与算法】LeetCode:堆和快排
文章目录 LeetCode:堆和快排排序数组数组中的第K个最大元素 (Hot 100)前 K 个高频元素(Hot 100)数据流的中位数(Hot 100) LeetCode:堆和快排 排序数组 排序数组 双向切分实现快排…...

文档大师:打造一站式 Word 报告解决方案
前言 在政府、医院、银行、财务以及销售等领域,常常需要创建各种报告文件来展开工作汇报,譬如季度销售报告、年度总结报告、体检报告和保险合同等。在没有报表工具支持之前,这类报告主要通过 Word 制作,费时费力且难以维护&#…...

Python 数字专题:全方位解析整数
目录 1. 引言 2. 整数的基本概念 2.1 定义 2.2 整数的表示 2.3 创建整数 3. 整数的基本操作 3.1 算术运算 3.2 比较运算 3.3 位运算 4. 内置函数与方法 4.1 int() 函数 4.2 abs() 函数 4.3 pow() 函数 5. 整数的性能优化 5.1 大整数的处理 5.2 使用 numpy 6. 应…...

IP协议报文
一.IP协议报头结构 二.IP协议报头拆解 1.4位版本 实际上只有两个取值,分别是4和6,4代表的是IPv4,6代表的是IPv6。 2.4位首部长度 IP协议报头的长度也是边长的,单位是*4,这里表示的大小为0~15,当数值为1…...

【分布式微服务云原生】掌握分布式缓存:Redis与Memcached的深入解析与实战指南
掌握分布式缓存:Redis与Memcached的深入解析与实战指南 摘要: 本文深入探讨了分布式缓存在现代分布式系统中的重要性,详细分析了Redis和Memcached两种主流的分布式缓存解决方案的原理和使用场景。文章不仅提供了核心技术的深入解析ÿ…...

计算机毕业设计 基于Python的智能文献管理系统的设计与实现 Python+Django+Vue 前后端分离 附源码 讲解 文档
🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…...

如何查看NVIDIA Container Toolkit是否配置成功
要确认 NVIDIA Container Toolkit 是否已成功配置,可以按照以下步骤进行检查: 1.检查 NVIDIA 驱动程序 首先,确保你的系统已经正确安装了 NVIDIA 驱动程序,并且可以识别你的 GPU。你可以使用 nvidia-smi 命令来进行检查…...