我们在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("结束事务"); } }