Spring 的AOP-AspectJ静态实现

         在spring框架越来越风靡的时候,大家是否考虑过为什么spring如此受欢迎。spring的核心功能:IOC + AOP +事务管理;那么今天小编就带大家一起来深入了解spring的AOP:

✪ 为什么需要AOP

       在传统的OOP编程中以对象为核心,整个软件系统由一系列相互依赖的对象组成,而这些对象将被抽象成一个个类,并允许使用类的继承来管理类与类之间一般到特殊的关系。随着软件规模的扩大,专业化的分工越来越细致,以及OOP应用实践的不断增多,慢慢的出现了一些OOP无法解决的问题,如下图:




        如图一和图二所示,当系统的规模越来越大,而图一中的红色框内的代码需要需要修改时,就需要对当前系统中所有涉及到该代码块的方法进行修改??那么这种情况就没有解决方法吗??

       当然有,就是spring提供的AOP ,AOP专门用于处理系统中分布于各个模块(或不同的方法)中交叉的关注点的问题,常常通过AOP来处理一些具有横切性性质的系统级服务,如事务管理,安全检查,缓存,对象池管理等。

✪  使用AspectJ实现AOP

       AspectJ 是最早的,功能比较强大的aop实现之一,从spring2.0开始,spring  aop 就已经引入了对AspectJ的支持,并允许直接使用AspectJ进行AOP编程:

       1.下载并安装Aspect:http://www.eclipse.org/aspect/downloads.php

       2.配置环境变量

        PS:AspectJ是绿色软件,所以只需要解压,但是需要配置环境变量;具体的步骤这里不再赘述;

       3.AspectJ实现AOP实例

        首先编写两个简单的java类,这两个类用于模拟系统中的业务组件:

<span style="font-size:18px;">package testAOP;

public class Hello {
	//定义一个简单的方法,模拟应用中的业务逻辑方法
	public  void foo(){
		System.out.println("执行Hello组件的foo()方法");
	}
	
	//定义一个addUser的方法,模拟应用程序中添加用户的方法
	public int addUser(String name,String pass){
		System.out.println("执行Hello组件的addUser()方法" + name);
		
		return 20;
	}
	
}
</span>

       第二个组件  World.java

<span style="font-size:18px;">package testAOP;

public class World {
	//定义一个简单的方法,模拟应用程序中的业务逻辑方法
	public void bar(){
		System.out.println("执行World组件的bar()方法");
	}
}</span>

       定义一个AspectJTest.java 并编写一个main方法:

<span style="font-size:18px;">package testAOP;

public class AspectJTest {
	public static void main(String[] args) {
		Hello hello = new Hello();
		hello.foo();
		hello.addUser("孙悟空", "123456");
		
		World world = new World();
		world.bar();
	}
}</span>

       执行上述方法之后,可以打印出如下结果:

<span style="font-size:18px;">执行Hello组件的foo()方法
执行Hello组件的addUser()方法孙悟空
执行World组件的bar()方法</span>

      但是,如果用户提出需求:在执行所有的方法时必须检查该用户的权限,我们开发怎么办??拒绝用户的需求?可是用户是上帝!所以我们必须拥抱需求,满足客户的需求,但是满足需求的同时,又必须考虑程序的代码复用和扩展维护,所以我们坚决不能使用图一中的方式。因此我们需要使用Aspect对AOP的支持,所以需要添加一个特殊的java类:AuthAspect.java

<span style="font-size:18px;">package testAOP;

public <strong>aspect </strong>AuthAspect {
	//指定在执行testAOP包中任意类的任意方法之前执行下面的代码块
	//第一个星号表示返回值类型不限,第二个星号表示类名不限
	//第三个星号表示方法名不限,圆括号中 代表任意个数,类型不限的形参
	before():execution(* testAOP.*.*(..)){
		System.out.println("模拟进行权限检查");
	}
	
}
</span>

       由于该类的特殊性,我们必须使用ajc.bat命令来编译上面的程序,得出以下的运行结果:

<span style="font-size:18px;">模拟进行权限检查
执行Hello组件的foo()方法
模拟进行权限检查
执行Hello组件的addUser()方法孙悟空
模拟进行权限检查
执行World组件的bar()方法</span>

       所以使用AspectJ 的AOP之后,我们根本不用对hello和world的两个组件类进行修改,而且可以完美的满足用户的需求;因此,我们也可以使用这种方法满足用户对增加记录日志的需求:

<span style="font-size:18px;">package testAOP;

public aspect LogAspect {
	//定义一个PointCut,名为logPointCut
	//该PointCut代表了后面给出的切入点的表达式,这样就可以复用该切入点的表达式
	pointCut logPointcut():execution(* testAOP.*.*.(..));
	after():logPointcut()
	{
		System.out.println("模拟记录日志");
	}
	
}<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">  </span></span>

     编译该类,可以发现以下的执行结果:

<span style="font-size:18px;">模拟进行权限检查
执行Hello组件的foo()方法
模拟记录日志
模拟进行权限检查
执行Hello组件的addUser()方法孙悟空
模拟记录日志
模拟进行权限检查
执行World组件的bar()方法
模拟记录日志</span>

      当上述两种需求都实现之后,如果我们需要控制方法执行之前开启事务,方法执行完毕之后关闭事务要怎么实现呢?同样只要定义TxAspect.java即可:

<span style="font-size:18px;">package testAOP;

public aspect TxAspect {
	Object around:call(* testAOP.*.*(..)){
		System.out.println("模拟开启日志");
		
		//回调原先的方法
		Object rvt = proceed();
		
		System.out.println("模拟结束日志");
		return rvt;
	}
	
}</span>

       Object rvt = proceed(); 指定proceed()代表回调原来的目标方法,这样位于proceed()之前的代码会被添加在目标方法之前,位于之后的会被添加在目标 方法之后;

      当我们编译上面所有的java类,会发现系统中的两个组件中添加了很多新的内容:检查权限,日志记录和事务开启关闭,但我们却丝毫不用对两个组件类进行修改,而这就是Aspect的强大之处,所以Aspect通常被称为编译时增强的AOP框架;

     所以,AOP的实现可以分为两类

   *  静态AOP实现:在编译阶段对程序进行修改,即实现对目标类的增强,生成静态的AOP代理类;以AspectJ为代表;

   *  动态AOP实现:AOP框架在运行阶段动态生成AOP代理(在内存中使用jdk动态代理或cglib动态生成AOP代理类),以实现对目标对象的增强,以Spring  AOP为代表;

    由于篇幅原因,关于Spring AOP的介绍先到这里,欢迎大家继续关注spring的AOP实现!

     

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值