1.下载 jar
//core spring
compile "org.springframework:spring-context:$springVersion"
compile "org.springframework:spring-core:$springVersion"
compile "org.springframework:spring-webmvc:$springVersion"
compile "org.springframework:spring-aop:$springVersion"
compile "org.springframework:spring-expression:$springVersion"
compile "org.springframework:spring-beans:$springVersion"
compile "org.springframework:spring-aspects:$springVersion"
compile group: 'org.aopalliance', name: 'com.springsource.org.aopalliance', version: '1.0.0'
compile group: 'org.aspectj', name: 'com.springsource.org.aspectj.weaver', version: '1.6.8.RELEASE'
1.定义接口
package com.boce.aop;
public interface AopTest {
public int add(int i, int j);
public int sub(int i, int j);
public int mul(int i, int j);
public int div(int i, int j);
}
2.接口实现:
package com.boce.aop;
import org.springframework.stereotype.Component;
@Component
public class AopTestImp implements AopTest{
public int add(int i, int j) {
int result = i + j;
return result;
}
public int sub(int i, int j) {
int result = i - j;
return result;
}
public int mul(int i, int j) {
int result = i * j;
return result;
}
public int div(int i, int j) {
int result = i / j;
return result;
}
}
3.aop 拦截:
package com.boce.aop;
import java.util.Arrays;
import java.util.List;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Order(1)
@Aspect
@Component
public class AopLogAspect {
/**
* 声明切入点表达式,一般在该方法中不再添加其他代码。
* 使用@Pointcut来声明切入点表达式。
* 后面的通知直接使用方法名来引用当前的切入点表达式。
*/
@Pointcut("execution(public int com.boce.aop.AopTestImp.*(..))")
public void declareJoinPointExpression() {}
/**
*前置通知,在目标方法开始之前执行。
*@Before("execution(public int com.spring.aop.impl.ArithmeticCalculator.add(int, int))")这样写可以指定特定的方法。
* @param joinpoint
*/
@Before("declareJoinPointExpression()")
//这里使用切入点表达式即可。后面的可以都改成切入点表达式。如果这个切入点表达式在别的包中,在前面加上包名和类名即可。
public void beforeMethod(JoinPoint joinpoint) {
String methodName = joinpoint.getSignature().getName();
List
System.out.println("前置通知:The method "+ methodName +" begins with " + args);
}
/**
*后置通知,在目标方法执行之后开始执行,无论目标方法是否抛出异常。
*在后置通知中不能访问目标方法执行的结果。
* @param joinpoint
*/
@After("execution(public int com.boce.aop.AopTestImp.*(int, int))")
public void afterMethod(JoinPoint joinpoint) {
String methodName = joinpoint.getSignature().getName();
//List
System.out.println("后置通知:The method "+ methodName +" ends ");
}
/**
*返回通知,在方法正常结束之后执行。
*可以访问到方法的返回值。
* @param joinpoint
* @param result 目标方法的返回值
*/
@AfterReturning(value="execution(public int com.boce.aop.AopTestImp.*(..))", returning="result")
public void afterReturnning(JoinPoint joinpoint, Object result) {
String methodName = joinpoint.getSignature().getName();
System.out.println("返回通知:The method "+ methodName +" ends with " + result);
}
/**
*异常通知。目标方法出现异常的时候执行,可以访问到异常对象,可以指定在出现特定异常时才执行。
*假如把参数写成NullPointerException则只在出现空指针异常的时候执行。
* @param joinpoint
* @param e
*/
@AfterThrowing(value="execution(public int com.boce.aop.AopTestImp.*(..))", throwing="e")
public void afterThrowing(JoinPoint joinpoint, Exception e) {
String methodName = joinpoint.getSignature().getName();
System.out.println("异常通知:The method "+ methodName +" occurs exception " + e);
}
/**
* 环绕通知类似于动态代理的全过程,ProceedingJoinPoint类型的参数可以决定是否执行目标方法。
* @param point 环绕通知需要携带ProceedingJoinPoint类型的参数。
* @return 目标方法的返回值。必须有返回值。
*/
/*
@Around("execution(public int com.boce.aop.AopTestImp.*(..))")
public Object aroundMethod(ProceedingJoinPoint point) {
Object result = null;
String methodName = point.getSignature().getName();
try {
//前置通知
System.out.println("The method "+ methodName +" begins with " + Arrays.asList(point.getArgs()));
//执行目标方法
result = point.proceed();
//翻译通知
System.out.println("The method "+ methodName +" ends with " + result);
} catch (Throwable e) {
//异常通知
System.out.println("The method "+ methodName +" occurs exception " + e);
throw new RuntimeException(e);
}
//后置通知
System.out.println("The method "+ methodName +" ends");
return result;
}
*/
}
3.配置文件:
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" 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.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">
4.测试类
package com.boce.aop;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.boce.aop.AopTest;
//@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration(locations = { "classpath:aopContext-service.xml" })
public class AopTestMain {
public static void main(String[] args) {
// 创建spring IOC容器
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("aopContext-service.xml");
// 从IOC容器中获取bean实例
AopTest aopTest = applicationContext.getBean(AopTest.class);
int result = aopTest.add(4, 6);
System.out.println(result + "");
result = aopTest.sub(4, 6);
System.out.println(result);
System.out.println(result);
result = aopTest.mul(4, 6);
System.out.println(result);
System.out.println(result);
result = aopTest.div(4, 0);
System.out.println(result);
}
}
注意:当对Controller 层进行aop 拦截时,配置文件一定要配置在 spring-mvc 的文件中,否则AOP无效
执行结果: