Spring框架使用Api接口实现AOP的切面编程、两种方式的程序示例以及Java各数据类型及基本数据类型的默认值/最大值/最小值列表

news2024/11/26 2:46:49

一、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 stub
		System.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/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
        https://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/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
        https://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{
    @Override
    public void insert() {
        System.out.println("insert one record.");
    }

    @Override
    public 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

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

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

相关文章

JAVA-异常(通俗易懂)

目录 一、异常的概念 1.算术异常 2.数组越界异常 3.空指针异常 二、异常体系结构 三、异常的分类 1. 编译时异常 2. 运行时异常 四、异常处理 1.防御式编程 2.异常的抛出 3.异常的捕获 4.try-catch捕获并处理 5.finally 五、异常的处理流程 六. 自定义异常类…

ade20k 街景图像【数据集】及其【论文出处】ADE20K数据集 超过25000张图像的语义分割数据集

ade20k 街景图像【数据集】及其【论文出处】ADE20K数据集介绍 是一个包含超过25000张图像的语义分割数据集&#xff0c;这些图像被密集注释&#xff0c;覆盖室内和室外场景。 它由MIT发布&#xff0c;包含100个事物类别和50个物质类别&#xff0c; 用于训练和验证的图像数量分别…

(16)MATLAB仿真Nakagami-m分布1

文章目录 前言一、Nakagami分布二、MATLAB建模代码三、仿真结果画图四、总结 前言 Nakagami衰落模型最初是由于该模型与短波电离层传播的经验结果相匹配而提出的。它还用于仿真来自多个干扰源的情况&#xff0c;因为多个独立且同分布&#xff08;i.i.d&#xff09;的瑞利分布随…

线程池的实现和讲解:解决多线程并发服务器创建销毁线程消耗过大的问题

1.前言 多进程/线程并发服务器、多路I/O转接服务器的简单实现-CSDN博客 原先的多线程并发服务器&#xff0c;有多少个客户端连接服务器就有多少个线程&#xff0c;CPU需要在多个线程之间来回切换处理客户端的请求&#xff0c;系统消耗比较大(每次创建和消耗线程在操作系统内部…

linux学习--第七天(多路复用IO)

多路复用IO -阻塞IO与非阻塞IO -IO模型 IO的本质时基于操作系统接口来控制底层的硬件之间数据传输&#xff0c;并且在操作系统中实现了多种不同的IO方式&#xff08;模型&#xff09;比较常见的有下列三种&#xff1a; 1.阻塞型IO模型 2.非阻塞型IO模型 3.多路复用IO模型 -阻…

开源2+1链动模式AI智能名片O2O商城小程序源码:线下店立体连接的超强助力器

摘要&#xff1a;本文将为您揭示线下店立体连接的重大意义&#xff0c;您知道吗&#xff1f;线上越火&#xff0c;线下就得越深入经营。现代门店可不再只是卖东西的地儿&#xff0c;还得连接KOC呢&#xff01;咱们来看看门店要做的那些超重要的事儿&#xff0c;还有开源21链动模…

Authentication Lab | CVE-2019-7644 - JWT Signature Disclosure

关注这个靶场的其他相关笔记&#xff1a;Authentication Lab —— 靶场笔记合集-CSDN博客 0x01&#xff1a;JWT Signature Disclosure 前情提要 本关的考点是 JWT&#xff08;Json Web Token&#xff09;漏洞&#xff0c;JWT 是一个用于跨域认证的技术。如果你不了解 JWT&…

计算机视觉——图像修复综述篇

目录 1. Deterministic Image Inpainting 判别器图像修复 1.1. sigle-shot framework (1) Generators (2) training objects / Loss Functions 1.2. two-stage framework 2. Stochastic Image Inpainting 随机图像修复 2.1. VAE-based methods 2.2. GAN-based methods …

攻防世界----->easyre-153

做题笔记。 下载 查壳。 UPX&#xff0c;---脱壳。 32ida打开。 先运行一下&#xff1a; 查找字符校位。 管道父子&#xff1f;有点像此前做的那个进程互斥。。。 分析&#xff1a; 跟进lol &#xff1f; 查看汇编窗口看看。(因为一个函数只存在一个打印函数&#xff0c;就很…

集合框架01:集合的概念、Collection体系、Collection接口

1.集合的概念 集合是对象的容器&#xff0c;定义了多个对象进行操作的常用方法。可实现数组的功能。 集合和数组的区别&#xff1a; 1.数组长度固定&#xff0c;集合长度不固定&#xff1b; 2.数组可以存储基本类型和引用类型&#xff0c;集合只能存储引用类型&#xff1b; …

读数据湖仓06数据集成

1. 数据湖仓中的数据集成 1.1. 数据湖仓的总体目标是为每一个人提供支持&#xff0c;包括从普通职员到CEO 1.2. 有了作为基础设施的基础数据&#xff0c;企业等组织才能实现真正的数据驱动 1.3. 提供组织所需的数据&#xff0c;最关键的一环在于提供集成的数据基础 1.3.1. 只…

信息安全工程师(32)认证技术方法

前言 认证技术方法是用于验证用户、设备或系统身份的各种技术手段和方法&#xff0c;旨在确保只有经过验证的实体才能访问系统资源&#xff0c;从而保护数据和系统的安全。 一、常见认证技术方法 密码认证 描述&#xff1a;用户通过输入预先设置的密码进行身份验证。优点&#…

The 14th Jilin Provincial Collegiate Programming Contest

题目 #include <bits/stdc.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second #define lson p << 1 #define rson p << 1 | 1 #define ll long long #define pii pair<int, int> #define ld lo…

C语言 | Leetcode C语言题解之第455题分发饼干

题目&#xff1a; 题解&#xff1a; int cmp(int* a, int* b) {return *a - *b; }int findContentChildren(int* g, int gSize, int* s, int sSize) {qsort(g, gSize, sizeof(int), cmp);qsort(s, sSize, sizeof(int), cmp);int m gSize, n sSize;int count 0;for (int i …

D26【python 接口自动化学习】- python 基础之判断与循环

day26 语句嵌套 学习日期&#xff1a;20241003 学习目标&#xff1a;判断与循环&#xfe63;-36 语句嵌套&#xff1a;如何处理多重嵌套的问题&#xff1f; 学习笔记&#xff1a; 语句嵌套的用途 在条件语句中使用另外一个条件语句 在循环中使用条件语句 多重循环 总结 1…

Authentication Lab | JWT None Algorithm

关注这个靶场的其他相关笔记&#xff1a;Authentication Lab —— 靶场笔记合集-CSDN博客 0x01&#xff1a;JWT None Algorithm 前情提要 本关的考点是 JWT&#xff08;Json Web Token&#xff09;漏洞&#xff0c;JWT 是一个用于跨域认证的技术。如果你不了解 JWT&#xff0c…

<<迷雾>> 第6章 加法机的诞生(3)--三比特加法电路 示例电路

用全加器组成一个三比特加法电路 info::操作说明 鼠标单击开关切换开合状态 primary::在线交互操作链接 https://cc.xiaogd.net/?startCircuitLinkhttps://book.xiaogd.net/cyjsjdmw-examples/assets/circuit/cyjsjdmw-ch03-02-3-bit-adder.txt 原图 加法机的简单图示 info::操…

Python案例--数字组合

在编程和数据处理中&#xff0c;我们经常需要从给定的元素中生成所有可能的组合。本文将通过一个简单的Python程序&#xff0c;展示如何生成由四个给定数字&#xff08;0-9&#xff09;组成的所有可能的无重复三位数组合。这可以应用于多种场景&#xff0c;如密码生成、数据校验…

【MySQL实战45讲6】全局锁和表锁

文章目录 全局锁表级锁 全局锁 顾名思义&#xff0c;全局锁就是对整个数据库实例加锁。MySQL提供了一个对全局读锁的方法&#xff0c;命令是Flush tables with read lock (FTWRL) 当需要让整个库处于只读状态的时候&#xff0c;可以使用这个命令&#xff0c;之后其他线程的以下…

计算机毕业设计python+spark知识图谱课程推荐系统 课程预测系统 课程大数据 课程数据分析 课程大屏 mooc慕课推荐系统 大数据毕业设计

《PythonSpark知识图谱课程推荐系统》开题报告 一、研究背景与意义 随着互联网技术的快速发展&#xff0c;在线教育平台已成为人们获取知识、提升技能的重要途径。然而&#xff0c;面对海量的课程资源&#xff0c;用户往往难以快速找到符合自己兴趣和需求的课程。传统的课程推…