实现过程:

1.pom引包

  <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2.写你的aspect

@Aspect
@Component
public class InlogAspect { @Autowired
private PipeInLogMapper pipeInLogMapper; /**
* 定义切点 @Pointcut
* 在注解的位置切入代码
*/
@Pointcut("execution(* com.zytcft.pipe.server.controller.Zytc*.*(..))")
public void logPointCut() {
System.out.println("切面已进入");
} @Around("logPointCut()")
public void saveSysLog(ProceedingJoinPoint joinPoint) throws Throwable {
//前置操作
//保存日志
PipeInLog log = new PipeInLog();
//从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//获取切入点所在的方法
Method method = signature.getMethod();
//获取方法的注解
ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
//根据注解获取value
log.setInterfaceName(apiOperation.value());
// 获取请求的类名
String className = joinPoint.getTarget().getClass().getName();
//获取请求的方法名
String methodName = method.getName();
log.setInterfaceCode(className + "." + methodName);
//请求的参数
Object[] paramsArray = joinPoint.getArgs();
//将参数所在的数组转换成json
String params = JSON.toJSONString(paramsArray[0]);
log.setInputParam(params);
//将参数所在的数组转换成json
JSONObject jsonObject = JSONObject.parseObject(params);
String flowId = jsonObject.getString("flowId");
log.setFlowId(flowId);
String contractId = jsonObject.getString("contractId");
log.setContractId(contractId);
//request 和 response 留着用
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
//通过这获取到方法的所有参数名称的字符串数组
String[] parameterNames = signature.getParameterNames();
log.setStatus("0");
try {
//让目标方法执行之后的就是后置行为了
Response reslut = (Response) joinPoint.proceed();
boolean isSuccess = reslut.isSuccess();
if (isSuccess) {
log.setStatus("1");
} else {
log.setStatus("9");
}
} catch (Exception e) {
log.setException(e.getMessage());
} finally {
pipeInLogMapper.insert(log);
}
}
}

还有其他的行为:

@AfterThrowing(pointcut = "webPointcut()", throwing = "e")//切点在webpointCut()
public void handleThrowing(JoinPoint joinPoint, Exception e) {//controller类抛出的异常在这边捕获}
@AfterReturning(value = "execution(* com.zy.test.controller.*.*(..)))", returning = "returnVal")
public void returnProcess(JoinPoint joinPoint, Object returnVal) {}
@Before("execution(* com.zy.test.controller.*.*(..))")
public void beforeProcess(JoinPoint joinPoint) {}

注意事项:

如果想要获取异常就必须让异常抛出 如果在目标方法体异常被捕获 则无法记录异常信息

类上必须加 @Aspect @Component 注解  因为需要通过类路径扫描自动检测它们,就像任何其他Spring管理bean一样,因此在启动类要使用@ComponentScan对其进行扫描

@ComponentScan(basePackages = {"com.zytcft.kernel","com.alibaba.cola","com.zytcft.pipe.server"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

@Aspect:作用是把当前类标识为一个切面供容器读取
@Pointcut:Pointcut是植入Advice的触发条件。每个Pointcut的定义包括2部分,一是表达式,二是方法签名。方法签名必须是 public及void型。可以将Pointcut中的方法看作是一个被Advice引用的助记符,因为表达式不直观,因此我们可以通过方法签名的方式为 此表达式命名。因此Pointcut中的方法只需要方法签名,而不需要在方法体内编写实际代码。
@Around:环绕增强,相当于MethodInterceptor
@AfterReturning:后置增强,相当于AfterReturningAdvice,方法正常退出时执行
@Before:标识一个前置增强方法,相当于BeforeAdvice的功能,相似功能的还有
@AfterThrowing:异常抛出增强,相当于ThrowsAdvice
@After: final增强,不管是抛出异常或者正常退出都会执行

AOP原理

AOP(这里的AOP指的是面向切面编程思想,而不是Spring AOP)主要的的实现技术主要有Spring AOP和AspectJ。
1、AspectJ的底层技术。
       AspectJ的底层技术是静态代理,即用一种AspectJ支持的特定语言编写切面,通过一个命令来编译,生成一个新的代理类,该代理类增强了业务类,这是在编译时增强,相对于下面说的运行时增强,编译时增强的性能更好。
2、Spring AOP
       Spring AOP采用的是动态代理,在运行期间对业务方法进行增强,所以不会生成新类,对于动态代理技术,Spring AOP提供了对JDK动态代理的支持以及CGLib的支持。
       JDK动态代理只能为接口创建动态代理实例,而不能对类创建动态代理。需要获得被目标类的接口信息(应用Java的反射技术),生成一个实现了代理接口的动态代理类(字节码),再通过反射机制获得动态代理类的构造函数,利用构造函数生成动态代理类的实例对象,在调用具体方法前调用invokeHandler方法来处理。
       CGLib动态代理需要依赖asm包,把被代理对象类的class文件加载进来,修改其字节码生成子类。
       但是Spring AOP基于注解配置的情况下,需要依赖于AspectJ包的标准注解,但是不需要额外的编译以及AspectJ的织入器,而基于XML配置不需要。

最新文章

  1. angularjs + fis +modJS 对于支持amd规范的组建处理(PhotoSwipe 支持,百度webUpload支持)
  2. 基于Arduino、STM32进行红外遥控信号接收
  3. setTimeout 和 setInterval
  4. -fomit-frame-pointer 编译选项在gcc 4.8.2版本中的汇编代码研究
  5. SQL判断语句用法和多表查询
  6. Python存取XML方法简介
  7. yum安装指定版本软件包__20160308
  8. 【正则】精通JS正则表达式,没消化 信息量太大,好文
  9. mac terminal终端ls命令参数详解
  10. C# 3.0 LINQ to XML
  11. type和instance
  12. struts2_4_为Action属性注入值
  13. CC/G++ 学习笔记
  14. android 优化之布局优化
  15. 涂抹mysql笔记-mysql管理工具
  16. 基于 Spring Cloud 完整的微服务架构实战
  17. GC垃圾收集器分类
  18. novaclient开发中遇到的问题小结
  19. jquery遍历集合&amp;数组&amp;标签
  20. 201621123037 《Java程序设计》第13周学习总结

热门文章

  1. NSSearchPathForDirectoriesInDomains用法
  2. ASI中POST请求和文件下载
  3. Android 子线程更新UI 异常
  4. WPF 使用Win32API 让控件置于WebBrowser上方
  5. Oracle 数据库启动与关闭
  6. IPV6-ONLY
  7. 利用Python爬虫轻松挣外快的几个方法(值得收藏)
  8. Python3 类与对象之王者荣耀对战小游戏
  9. C# 导出pdf(浏览器不预览直接下载)
  10. 小胖求学系列之-文档生成利器(下)-smart-doc