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 分别在方法执行起和末尾执行的方法。类的实现代码如下:

java">//接口类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的配置及运行结果如下:

java"><?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类,还有一个自定义的横切关注点(切面,即自定义类)。代码如下:

java">//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的代码及运行结果如下:

java">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; 还有一种方式是使用自定义类,先自己配置一个类实现方法前和方法后要切入的方法,然后加入切面中。

被切入的类内容如下:

java">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.");
    }
}

自定义要切入的方法内容类定义如下:

java">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.niftyadmin.cn/n/5689782.html

相关文章

指南:Linux常用的操作命令!!!

引言: 操作系统是软件的一类。 主要作用是协助用户调度硬件工作&#xff0c;充当用户和计算机硬件之间的桥梁。 尽管图形化是大多数人使用计算机的第一选择&#xff0c;但是在Linux操作系统上多数都是使用的&#xff1a;命令行在开发中&#xff0c;使用命令行形式&#xff0c…

SQL Server—如何使用IF Exists判断详解

SQL Server—如何使用IF Exists判断详解 语法: if exists (select * from 查询类型 where name 查询数据的名称) 1 判断数据库 1. 查询数据库如果存在则删除掉 -- where 条件查询 -- name 数据库名 -- database 数据库 存放表 -- 选择sysdatabases表数据库名为People的…

YOLO11改进|上采样篇|引入CARAFE上采样模块

目录 一、CARAFE上采样模块1.1CARAFE上采样模块介绍1.2CARAFE核心代码 五、添加MLCA注意力机制5.1STEP15.2STEP25.3STEP35.4STEP4 六、yaml文件与运行6.1yaml文件6.2运行成功截图 一、CARAFE上采样模块 1.1CARAFE上采样模块介绍 CARAFE 的主要思想&#xff1a; 将特征图的上采…

C(九)while循环 --- 军训匕首操情景

匕首操&#xff0c;oi~oi~oi~~~~~ 接下来的几篇推文&#xff0c;杰哥记录的是三大循环结构的运行流程及其变式。 本篇的主角是while循环。&#x1f449; 目录&#xff1a; while循环 的组成、运行流程及其变式关键字break 和 continue 在while 循环中的作用while 循环的嵌套题目…

扩展可持续性概念:太空移民、持久产品与人类未来

可持续性的扩展概念&#xff1a;超越绿色能源&#xff0c;关乎人类未来的延续 当我们听到“可持续性”这个词时&#xff0c;大多数人首先想到的是环境保护、绿色能源、减少碳足迹或保护生态系统。虽然这些都是不可忽视的重要部分&#xff0c;但可持续性远远超出了绿色能源的范…

移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——13.mapset(模拟实现)

1.对红黑树进行改造 1.1treenode模板参数改变 之前构建treenode模板参数传的是class k,class v(set为k&#xff0c;k&#xff1b;map是k&#xff0c;v&#xff09;&#xff0c;现在直接用T代替 template<class T> //这里直接传了T作为模板参数&#xff0c;T可能是pai…

ICM20948 DMP代码详解(60)

接前一篇文章:ICM20948 DMP代码详解(59) 上一回开始解析icm20948_set_fsr函数以及其中的inv_icm20948_set_fsr函数,本回继续。为了便于理解和回顾,再次贴出inv_icm20948_set_fsr函数源码,在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948Setup.c中,如下: i…