需要aop的依赖
配置文件中需要激活:
execution(* com.igeekhome.c30.aop.*.*(..))
第一个*表示任意返回值 ,第二个*表示任意类, 第三个*表示任意方法,(...) 表示任意参数
applicationContext.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<!-- 配置扫描包 -->
<context:component-scan base-package="com.igeek.crm" />
<!-- 3:配置aop的aspectj的自动代理: 自动扫描bean组件中,含有@Aspect的bean,将其作为aop管理,开启动态代理 -->
<aop:aspectj-autoproxy />
</beans>
定义切面MyAspect类:
package com.igeek.crm.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* @author www.igeehome.com
*
* TODO
*
* 2018年10月10日下午7:03:11
*/
@Component
@Aspect
public class MyAspect {
public MyAspect(){
System.out.println("123123");
}
@Pointcut(value="bean(*service)")
private void myPointcut2(){}
/**
* 环绕通知
* @param proceedingJoinPoint
* @return
* @throws Throwable
*/
@Around("myPointcut2()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
Object result = null;
System.out.println("---环绕通知开始---");
result = proceedingJoinPoint.proceed();//执行被代理对象的方法
System.out.println("---环绕通知结束---");
return result;
}
/**
* 后置通知
* @param joinPoint
* @param returnVal 拦截方法的返回值
*/
@AfterReturning(value="bean(*Service)",returning="returnVal")
public void afterReturing(JoinPoint joinPoint,Object returnVal){
System.out.println("---------后置通知-----得到返回值:"+returnVal+"-----");
}
//第一个前置通知
@Before("bean(*Service)")
public void firstBefor(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
System.out.println("拦截的方法名称:"+methodName);
String className = joinPoint.getTarget().getClass().getName();
System.out.println("拦截对象的类名:"+className);
System.out.println("代理对象:"+joinPoint.getThis().getClass().getName());
System.out.println("第一个前置通知......");
}
}
======================================================================================
列2:
execution(* com.igeekhome.c30.aop.*.*(..))
第一个*表示任意返回值 ,第二个*表示任意类, 第三个*表示任意方法,(...) 表示任意参数
package com.igeekhome.c30.aop;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
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;
//切面也需要交给IOC容器来管理,还需要告诉Spring,这个类是一个切面
@Component
@Aspect
@Order(1) //值越小优先级越高,使用场景 存在多个切面的方法
public class CalculatorAspect {
//在切面中advice通知包含前置通知(before),后置通知,环绕通知,返回通知,异常通知
//JoinPoint表示连接点,会包含切点的真实方法的一些相关信息
@Before("com.igeekhome.c30.pc.MyPointCut.pointCut()")
public void beforMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println(methodName+" method begin with "+Arrays.toString(args));
}
//在后置通知中不能访问方法调用的结果
@After("com.igeekhome.c30.pc.MyPointCut.pointCut()")
public void afterMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
System.out.println(methodName +" method end");
}
/*
//返回通知可以获取方法处理的结果,在返回通知中,可以获取连接点,也可以获取返回值,返回值的参数名称与注解中声明的名称一致
@AfterReturning(pointcut="execution(public int com.igeekhome.c30.aop.CalculatorImpl.*(int,int))",returning="result")
public void afterReturning(JoinPoint joinPoint,int result){
String methodName = joinPoint.getSignature().getName();
System.out.println(methodName +" method return with " + result);
}
//在异常通知中可以获取连接点,也可以获取异常对象
@AfterThrowing(pointcut="execution(public int com.igeekhome.c30.aop.CalculatorImpl.*(int,int))",throwing="e")
public void afterThrowing(JoinPoint joinPoint,Exception e){
String methodName = joinPoint.getSignature().getName();
System.out.println(methodName +" method throw with " + e);
}*/
/*//环绕通知其实可以包含方法调用的全过程,可以接受一个参数
@Around("execution(* com.igeekhome.c30.aop.*.*(..))")
public Object round(ProceedingJoinPoint proceedingJoinPoint){
Object object = null;
String name = proceedingJoinPoint.getSignature().getName();
//前置处理
System.out.println(name+"前置处理");
//表示调用真实的处理的方法
try {
object = proceedingJoinPoint.proceed();
System.out.println(name+"返回处理");
} catch (Exception e) {
System.out.println(name+"异常处理");
e.printStackTrace();
}finally {
System.out.println(name+"后置处理");
return object;
}
}*/
}