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是基于 内存存储的 基于内存,读写性能更高内存是不大的,只能存储热点信息 安装 绿色软件,安装即可使用 安装服务 手…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...

JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...