8.4.2: AspectJ 实现AOP

我们在C盘下写一个Hello.java :

package lee;

public class Hello{

	public static void main(String[] args){
	
		Hello h=new Hello();
		h.sayHello();
	}

	public void sayHello(){
	
		System.out.println("Hello AspectJ !");
	}
}
编译运行:

8.4.2: AspectJ 实现AOP_第1张图片

没有任何问题,程序的输出正是我们想要的。

假设现在客户需要在执行sayHello( )方法之前启动事务,方法结束之后关闭事务,在传统的编程模式下,我们必须手动修改sayHello( )方法------但是如果采用面向切面编程的思想,则可以无须修改sayHello( )方法,也可以达到同样的效果。这里我们使用AspectJ框架帮我们做到这一点。我们在C盘下写一个TransactionAspect.java

package lee;

public aspect TransactionAspect{
	
	//指定执行Hello.sayHello()方法时执行下面的代码块
	void around():call(void Hello.sayHello()){
	
		System.out.println("开启事务");
		proceed();//回调原来的sayHello()方法
		System.out.println("结束事务");
	}
}
上面的java文件不是使用class、interface或enum,而是使用 aspect,aspect是AspectJ才能识别的关键字。

8.4.2: AspectJ 实现AOP_第2张图片

我们可以把 ajc 命令理解成javac命令,它们都用于编译Java程序,区别是ajc命令可以识别AspectJ的语法,从这个意义上看,我们可以将ajc当成一个增强版的javac命令。

运行Hello类没有任何改变,但是程序的输出已经让我们足够惊喜了,对,就是我们想要的结果!

有了AOP,我们完全可以不对Hello.java类进行任何修改,同时又可以满足客户的需求。上面的程序只是在控制台打印输出语句模拟事务的开启和关闭,在实际工作中可以用实际的操作代码来代替打印语句,这就可以满足客户的要求了。

如果客户再次提出新需求,需要在sayHello( )方法后增加记录日志的功能,那也很简单,我们再写一个 LogAspect.java :

package lee;

public aspect LogAspect{

	pointcut logPointcut()
		:execution(void Hello.sayHello());

	after():logPointcut(){
		System.out.println("记录日志功能...");
	}
}
8.4.2: AspectJ 实现AOP_第3张图片

实际上,AspectJ允许同时为多个方法添加新功能,只要我们定义Pointcut时指定匹配更多的方法即可。如如下片段:

pointcut xxxPointcut()
   :execution(void H*.say*());
上面程序中的xxxPointcut将可以匹配所有以H开头的类中、所有以say开头的方法,但该方法返回的必须是void。如果想匹配任意的返回值类型:

pointcut xxxPointcut
   :execution(* H*.say*());

 修改:

Hello.java :

package lee;

public class Hello{

	public static void main(String[] args){
		Hello h=new Hello();
		h.sayHello();
		h.sayGoodbye();
	}

	public void sayHello(){
		System.out.println("Hello AspectJ !");
	}

	public void sayGoodbye(){
		System.out.println("Goodbye Java !");
	}
}
LogAspect.java :

package lee;

public aspect LogAspect{

	pointcut logPointcut()
		:execution(void Hello.say*());

	after():logPointcut(){
		System.out.println("记录日志功能...");
	}
}
TransactionAspect.java :

package lee;

public aspect TransactionAspect{
	
	//指定执行Hello.sayHello()方法时执行下面的代码块
	void around():call(void Hello.say*()){
	
		System.out.println("开启事务");
		proceed();//回调原来的sayHello()方法
		System.out.println("结束事务");
	}
}
8.4.2: AspectJ 实现AOP_第4张图片






你可能感兴趣的:(AOP,aspectj)