我们在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 !");
}
}编译运行:
没有任何问题,程序的输出正是我们想要的。
假设现在客户需要在执行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才能识别的关键字。
我们可以把 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("记录日志功能...");
}
}实际上,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("结束事务");
}
}
本文通过实例演示如何利用AspectJ框架实现面向切面编程(AOP),无需修改业务代码即可为方法添加事务管理和日志记录等功能。
1万+

被折叠的 条评论
为什么被折叠?



