Aspectj快速上手代码示例之Before,After,Around

本文不打算解释AOP的相关专业名词和概念,仅通过几个代码示例来展示Aspectj(对AOP实现的)的基本使用,并且使用的Aspectj是目前最新版本。

1.搭建环境

本文使用Maven来构建工程,通过aspectj-maven-plugin插件来编译*.aj文件至.class。

Maven的具体配置:

<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>aspectj-maven-plugin</artifactId>
				<version>1.7</version>
				<configuration>
					<complianceLevel>1.6</complianceLevel>
				</configuration>
			</plugin>

在上面的configuration节点下可以配置

<aspectDirectory></aspectDirectory>

默认是src/main/aspect , 可以根据需要进行设置。

配置aspectj运行时环境依赖jar

<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>1.8.2</version>
		</dependency>

2.创建一个普通的Java类(Simple.java),为接下来使用Aspectj来植入相应功能做准备

package com.rft.fdsi.server.aop;

public class Simple {

	static {
		System.out.println("[src] static init");
	}

	public Simple() {
		System.out.println("[src] construct");
	}

	public String welcome(String name) {
		System.out.println("[src]===========start===========");
		System.out.println("[src] welcome method execute");
		System.out.println("[src] welcome method execute");
		System.out.println("[src]===========end===========");
		// throw new RuntimeException("runtime exception");
		return "welcome " + name;
	}

	public static void main(String[] args) {
		Simple simple = new Simple();
		String greeting = simple.welcome("Jack");
		System.out.println(greeting);
	}
}

3.创建一个针对Simple类的静态代码块初始化,构造方法执行,方法调用进行植入功能的方面类(SimpleAspect.aj)。

package com.rft.fdsi.server.aop;

public aspect SimpleAspect {

	public pointcut staticInit() : staticinitialization(com.rft.fdsi.server.aop.Simple);

	before() : staticInit() {
		System.out.println("[before]"
				+ thisJoinPointStaticPart.getSignature().getName());
	}

	after() returning() : staticInit() {
		System.out.println("[after returning]"
				+ thisJoinPointStaticPart.getSignature().getName());
	}

	before() : call(public com.rft.fdsi.server.aop.*.new()) {
		System.out.println("[before]" + thisJoinPoint.getSignature().getName());
	}

	after() : call(public com.rft.fdsi.server.aop.*.new()) {
		System.out.println("[after]" + thisJoinPoint.getSignature().getName());
	}

	public pointcut welcomeMethod(String name) : call(public String com.rft.fdsi.server..*.welcome(String)) && args(name);

	before(String name): welcomeMethod(name){
		System.out
				.println("[before]"
						+ thisJoinPoint.getTarget().getClass()
								.getCanonicalName() + "."
						+ thisJoinPoint.getSignature().getName()
						+ " args_name=" + name);
	}

	after(String name) returning(String retval) : welcomeMethod(name) {
		System.out.println("[after returning]"
				+ thisJoinPoint.getTarget().getClass().getCanonicalName() + "."
				+ thisJoinPoint.getSignature().getName() + " args_name=" + name
				+ " return_value =" + retval);

	}

	after(String name) : welcomeMethod(name){
		System.out
				.println("[after]"
						+ thisJoinPoint.getTarget().getClass()
								.getCanonicalName() + "."
						+ thisJoinPoint.getSignature().getName()
						+ " args_name=" + name);
	}

	after(String name) throwing(java.lang.Exception e) : welcomeMethod(name)
	 {
		System.out.println("[after throwing]"
				+ thisJoinPoint.getTarget().getClass().getCanonicalName() + "."
				+ thisJoinPoint.getSignature().getName() + " throwing="
				+ e.getMessage());
	}
}

上面显示的声明了两个切入点(Pointcut)分别是:staticInit()(该切入点的连接点是Simple类的静态代码块), welcomeMethod(name)(该切入点的连接点是Simple对象的welcomeMethod方法);隐式的在前置通知和后置通知中声明了相同的切入点,该切入点的连接是Simple的构造方法。

上面使用到了Aspectj内置的5中通知类型的四种:before(连接点执行前通知)after returning(连接点正常完成后通知),after throwing(连接点执行中发生异常后通知),after(连接点完成后通知,无论正常还是异常)。另外一种是around(环绕通知,在连接点执行前,执行完成后都通知)。

使用aspectj-maven-pugin来编译SimpleAspect.aj文件,执行命令:mvn aspectj:compile 即可。

4.测试效果

public static void main(String[] args) {
		Simple simple = new Simple();
		String greeting = simple.welcome("Jack");
		System.out.println(greeting);
	}

如果没有Aspject的植入的话,上面输入的结果应该是Simple中的输入内容加上"welcome Jack",现在执行的结果如下图所示:

after throwing通知没有执行,去掉Simple类中welcome方法中的异常抛出注释,并且注释掉返回值,执行测试,将可以看到after throwing在连接点welcome执行发送异常后执行通知。

5.添加around通知在SimpleAspect.aj方面类中,另外需要注释掉其中welcomeMethod切入点表达式上的after和before通知,因为同时指定before,after,around将无发确定其执行的顺序,而且指定around通知后没必要存在before,after通知,around通知是可以实现这两种通知的效果的。

String around(String name) : welcomeMethod(name){
		System.out.println("[around]========start=========");
		System.out
				.println("[around]"
						+ thisJoinPoint.getTarget().getClass()
								.getCanonicalName() + "."
						+ thisJoinPoint.getSignature().getName()
						+ " args_name=" + name);
		String retval = proceed(name);
		System.out.println("[around]"
				+ thisJoinPoint.getTarget().getClass().getCanonicalName() + "."
				+ thisJoinPoint.getSignature().getName() + " args_name=" + name
				+ " return_value=" + retval);
		System.out.println("[around] modify return value append ‘!!!‘ = "
				+ (retval = retval + "!!!"));
		System.out.println("[around]========end=========");
		return retval;
	}

执行测试后可以看到下图,around通知在连接点welcome方法出执行,其在连接点执行前打印输出内容,在连接点执行完成后获取到返回值,并加以修改后返回。around通知在五中通知类型中最为强大,实际应用中则根据要植入的功能情况加以选择即可。

至此示例到此为止,关于Aspjectj更多信息参见官网:http://www.eclipse.org/aspectj/docs.php

时间: 2024-12-29 01:42:31

Aspectj快速上手代码示例之Before,After,Around的相关文章

快速上手代码示例 Java后台最新框架

A 代码生成器(开发利器);     增删改查的处理类,service层,mybatis的xml,SQL( mysql   和oracle)脚本,   jsp页面 都生成   就不用写搬砖的代码了,生成的放到项目里,可以直接运行B 阿里巴巴数据库连接池druid;  数据库连接池  阿里巴巴的 druid.Druid在监控.可扩展性.稳定性和性能方面都有明显的优势C 安全权限框架shiro ;  Shiro 是一个用 Java 语言实现的框架,通过一个简单易用的 API 提供身份验证和授权,更安

学习Keras:《Keras快速上手基于Python的深度学习实战》PDF代码+mobi

有一定Python和TensorFlow基础的人看应该很容易,各领域的应用,但比较广泛,不深刻,讲硬件的部分可以作为入门人的参考. <Keras快速上手基于Python的深度学习实战>系统地讲解了深度学习的基本知识.建模过程和应用,并以深度学习在推荐系统.图像识别.自然语言处理.文字生成和时间序列中的具体应用为案例,详细介绍了从工具准备.数据获取和处理到针对问题进行建模的整个过程和实践经验. <Keras快速上手>PDF,531页,带书签目录,彩色配图,文字可以复制. 配套源代码和

入门python:《Python编程快速上手让繁琐工作自动化》中英文PDF+代码

入门推荐学习<python编程快速上手>前6章是python的基础知识,通俗易懂地讲解基础,初学者容易犯错的地方,都会指出来.从第三章开始,每章都有一个实践项目,用来巩固前面所学的知识. 从第七章开始就是书名中的后半部:让繁琐工作自动化.每个章节都可独立出来.每看完一个章节,你都能将其中的知识点融会贯通,用到自己的日常工作中,提高效率.第九章 组织文件对系统管理员非常有用,能够指挥程序完成复制 备份文件(夹)操作.第十一章是web抓取信息,介绍了主流的request beautifulSoup

R语言快速上手入门

R语言快速上手入门 课程学习网址:http://www.xuetuwuyou.com/course/196 课程出自学途无忧网:http://www.xuetuwuyou.com 课程简介 本教程深入浅出地讲解如何使用R语言玩转数据.课程中涵盖R语言编程的方方面面,内容涉及R对象的类型.R的记号体系和环境系统.自定义函数.if else语句.for循环.S3类R的包系统以及调试工具等.本课程还通过示例演示如何进行向量化编程,从而对代码进行提速并尽可能地发挥R的潜能.本课程适合立志成为数据科学家的

《Python编程快速上手 让繁琐工作自动化》pdf

<div id="article_content" class="article_content tracking-ad" data-mod="popu_307" data-dsm="post"> <p><br></p><p>下载地址:<a target="_blank" href="https://page74.ctfile.co

MongoDB快速上手

1.  MongoDB简介 MongoDB是一个跨平台的基于Key_Value键值对形式保存数据的NoSQL文档类型数据库. NoSQL(not only sql)数据库,泛指非关系型数据库. 1.1 NoSQL数据库的特点 l  不需要预定义模式 不需要事先定义数据模式,预定义表结构.数据中的每条记录都可能有不同的属性和格式.当插入数据时,并不需要预先定义它们的模式. l  无共享架构 相对于将所有数据存储的存储区域网络中的全共享架构.NoSQL往往将数据划分后存储在各个本地服务器上.因为从本

如何R语言快速上手入门

R语言快速上手入门 课程学习网址:http://www.xuetuwuyou.com/course/196 课程出自学途无忧网:http://www.xuetuwuyou.com 课程简介 本教程深入浅出地讲解如何使用R语言玩转数据.课程中涵盖R语言编程的方方面面,内容涉及R对象的类型.R的记号体系和环境系统.自定义函数.if else语句.for循环.S3类R的包系统以及调试工具等.本课程还通过示例演示如何进行向量化编程,从而对代码进行提速并尽可能地发挥R的潜能.本课程适合立志成为数据科学家的

Extjs视频教程_快速上手Extjs4.2实战开发

Extjs视频教程_快速上手Extjs4.2实战开发快速上手Extjs4.2并熟练搭建基于MVC4+FluentData+Spring.net和T4模板的企业级项目架构适合人群:中级课程分类:.NET+ExtJs课时数量:76课时用到技术:Extjs4.2,MVC4,FluentData,T4,Spring.net涉及项目:基于Extjs4.2的丰富案例.一个独立的企业级架构和综合演示案例咨询qq:1840215592 Extjs视频教程课程大纲:(1)Extjs4.2理论部分(风舞烟老师老师主

离线消息如何实现?-- ESFramework 4.0 快速上手(02)

在ESFramework 4.0 快速上手一文中,主要介绍了如何使用ESPlus.Rapid命名空间中的引擎来快速地构建基于TCP的网络通信系统,即使是使用ESPlus.Rapid来进行ESFramework快速开发,也还有很多可以介绍的内容,于是,我想再多写几篇文章来说明现实通信系统中的一些常见需求如何使用ESFramework快速实现.本文是为第一篇,介绍离线消息的原理和实现. 一.如何截获离线消息 阅读了ESFramework 4.0 快速上手朋友都知道,一个在线用户给另一个用户发送文本信