Spring的AOP(一)

2014-11-24 02:40:49 · 作者: · 浏览: 3

一、概述

因为软件系统需求变更是很频繁的事情,系统可能对前期设计的方法进行不断的更改,如增加事务控制、合法性验证、记录日志等。我们希望有一种特殊的方法,我们只要定义该方法,无须在原方法中显示调用它,系统会自动执行该特殊方法。这就是AOP,它专门用于处理系统中分布于各个模块中的交叉关注点的问题,处理一些具有横切性质的系统级服务,如事务管理、安全检查、缓存、对象池管理等。

二、AspectJ 对AOP的实现

AspectJ是一个基于Java语言的AOP框架,是Eclipse下面的一个开源子项目,主要包括两部分:第一部分定义了如何表达、定义AOP编程中的语法规范;另一部分是工具部分,包括编译、调试工具等。

1.2 AspectJ安装:启动命令行窗口,进入刚下载aspectj-1.6.10.jar文件所在路径,输入如下命令:java -jar aspectj-1.6.10.jar,在弹出窗口中点击 Next --> 选择jdk安装路径 Next --> 选择安装目录 Install --> Next --> Finish。

1.3 在Path环境变量中添加 ...aspectj1.6in,在CLASSPATH环境变量中添加 ...aspectj1.6libaspectjrt.jar。

2. AspectJ基本使用

2.1 定义一个Java类 Hello.java

package lee;
public class Hello {
//定义一个简单方法,模拟应用中的业务逻辑方法
public void sayHello(){
System.out.println(Hello AspectJ!);
}
public static void main(String[] args){
Hello h = new Hello();
h.sayHello();
}
}

2.2 定义一个特殊的Java类(但并不是一个Java类),需要在执行sayHello()方法前启动事务,方法执行结束时关闭事务。

package lee;
public aspect TxAspect{
//指定执行Hello.sayHello()方法时执行下面代码块
void around():call(void Hello.sayHello()){
System.out.println(开始事务...);
proceed(); // 调用原来的sayHello()方法
System.out.println(事务结束...);
}
}

2.3 再定义一个特殊的Java类,在执行sayHello()方法后记录日志。

package lee;
public aspect LogAspect {
//定义一个PointCut,其名为logPointcut
//该PointCut对应于指定Hello对象的sayHello方法
pointcut logPointcut() :execution(void Hello.sayHello());
//在logPointcut之后执行下面代码块
after():logPointcut(){
System.out.println(记录日志...);
}
}

注意:Java无法识别TxAspect.java文件的内容,所以我们要使用ajc.exe命令来编译上面的java内容:ajc -d . hello.java TxAspect.java。

三、Spring的AOP支持

AOP从程序运行角度考虑程序的流程,提取业务处理过程的切面。AOP面向的是程序运行中各个步骤,希望以更好的方式来组合业务处理的各个步骤。框架具有两个特征:各步骤之间的良好隔离性;源代码无关性。

Spring中AOP代理由Spring的IoC容器负责生成、管理,因此AOP代理可以直接使用容器中的其它Bean实例作为目标。Spring AOP使用纯Java实现,它不需要专门的编译过程,目前只支持将方法调用作为连接点。

1. 基于Annotation的零配置方式

1.1 定义一个Service接口

package test.service;
public interface Person {
public String sayHello(String name);
public void eat(String food);
}

1.2 实现Service接口

package test.service.impl;
import org.springframework.stereotype.*;
import test.service.Person;
@Component
public class Chinese implements Person {
public String sayHello(String name) {
return name + Hello , Spring AOP;
}
public void eat(String food) {
System.out.println(我正在吃: + food);
}
}

1.3 配置Spring配置文件 bean.xml


xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xmlns:context=http://www.springframework.org/schema/context
xmlns:aop=http://www.springframework.org/schema/aop
xsi:schemaLocation=http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd>






1.4 定义一个用于Before增强处理的切面

package test.advice;
import org.aspectj.lang.annotation.*;
//定义一个切面
@Aspect
public class BeforeAdviceTest {
// 匹配test.service.impl包下所有类的、所有方法的执行作为切入点
@Before(execution(* test.service.impl.*.*(..)))
public void authority() {
System.out.println(1.模拟执行权限检查);
}
}

1.5 测试

package test;
import org.springframework.context.*;
import org.springframework.context.support.*;
import test.service.*;

public class BeanTest {
public static void main(String[] args) {
Appl