一. AOP实现Helloworld
SpringAOP 中AspectJ是Java社区中最完整最流行的AOP框架,在Spring2.0以上的版本中,几乎都是使用基于AspectJ注解或者基于xml配置完成AOP。今天先讲注解。
步骤1:加入jar包
com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
commons-logging-1.1.3.jar
spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
步骤2:编写纯洁的实现类,需要放入到IOC容器管理
@Override
public int add(int x, int y) {
int result = x + y;
return result;
}
@Override
public int sub(int x, int y) {
int result = x - y;
return result;
}
@Override
public int mul(int x, int y) {
int result = x * y;
return result;
}
@Override
public int div(int x, int y) {
int result = x / y;
return result;
}
步骤3:编写切面类
package com.wanbangee.aop;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect //声明为一个切面类,切面类也需要放入到IOC容器中管理,才能成为一个真正的切面
@Component //切面也需要放入IOC容器管理
public class LoggingAspect {
/**
* 在 add,sub,mul,div 方法执行之前执行before方法
*/
//申明切入点表达式
//execution(public int com.wanbangee.aop.ArithmeticInterfaceImp.add(int,int))
// 执行 目标方法修饰符 返回值类型 方法的位置 方法所在的类 方法名 参数类型
@Before("execution(public int com.wanbangee.aop.ArithmeticInterfaceImp.add(int,int))")
public void before() {
System.out.println("the method begin...");
}
/**
* 在 add,sub,mul,div 方法执行之前执行after方法
*/
//申明切入点表达式
@After("execution(public int com.wanbangee.aop.ArithmeticInterfaceImp.add(int,int))")
public void after() {
System.out.println("the method end...");
}
}
步骤4 : 编写Spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.wanbangee.aop"></context:component-scan>
<!-- 使AspectJ注解生效:目的就是为匹配切入点的程序自动的生成目标代理对象 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
二. 切入点表达式
程序正常的执行了抽取的横切关注点,但是存在问题:在调用sub()方法时,横切关注点没有执行,我们的需求是ArithmeticInterface中的所有的业务方法都需要日志,而现在只有add()方法才有,不正常。所以我们要熟悉切入点配置的细节。
/**
* 切入点表达式配置细节:
* 第一个* 表示任何修饰符,人会返回值的方法
* 第二个* 表示com.wanbangee.aop包中人意类
* 第三个* 表示任意方法
* .. 表示任意参数的类型个数
*/
@Before("execution(* com.wanbangee.aop.*.*(..))")
public void before() {
System.out.println("the method begin...");
}
三.获取连接点的细节
我们目前在输出日志的时候,并没有输出 目标方法的方法名,方法参数,返回值等信息,所以我们要在界面类的通知里面获取连接点的细节。
@Before("execution(* com.wanbangee.aop.*.*(..))")
public void before(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();//获取方法名称
List<Object> args = Arrays.asList(joinPoint.getArgs());//获取参数
System.out.println("the method "+ methodName +" begin with " + args);
}
/**
* 在 add,sub,mul,div 方法执行之前执行after方法
*/
//申明切入点表达式
@After("execution(* com.wanbangee.aop.*.*(..))")
public void after(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();//获取方法名称
System.out.println("the method "+ methodName +" end...");
}
小结
开发AOP的工程的需要额外的导包;
配置文件中需要加入AOP的命名空间;
基于注解的配置方式,需要在配置文件中加入如下的配置:
<!-- 使AspectJ注解起作用:自动为匹配的类生成代理对象 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
切面类和目标类都必须放入IOC进行管理;
切面使用@Aspect注解标注;
在切面类中的方法标注@Before注解,表示的是前置通知,使用execution指定切入点表达式,通知的方法入参JoinPoint可以获取目标方法的细节。