在方法执行的前后,切入代码;经典的service层切入事务;
@Aspect注解是切面注解类
@Pointcut切点定义
@Before是方法执行前调用
@After是方法执行后调用
@AfterReturning方法执行返回值调用

Service层本身就可以切入事务,所以我们这类搞个常用的 切controller层方法

每个执行controller层的方法 都记录下请求Url,访问者IP 执行类方法参数等信息;

紧接上一讲,这里只是多了切面类,项目结构:

贴下代码:

1.切面类com.cy.aspect.RequestAspect.java:

package com.cy.aspect;

import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.cy.entity.Student;
import ch.qos.logback.classic.Logger; /**
* 切面类
*/
@Aspect
@Component
public class RequestAspect { private Logger logger= (Logger) LoggerFactory.getLogger(RequestAspect.class); /**
* Pointcut定义切点
* public修饰符的 返回值任意 com.cy.controller包下面的任意类的任意方法任意参数
*/
@Pointcut("execution(public * com.cy.controller.*.*(..))")
public void log(){ } @Before("log()")
public void doBefore(JoinPoint joinPoint){
logger.info("方法执行前...");
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = sra.getRequest();
logger.info("url: " + request.getRequestURI());  //url
logger.info("ip: " + request.getRemoteHost());   //ip
logger.info("method: "+request.getMethod()); //post or get? or ?
logger.info("class.method: " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
logger.info("args: "+joinPoint.getArgs());
Student student = (Student) joinPoint.getArgs()[0];
logger.info(student.toString());
} @After("log()")
public void doAfter(JoinPoint joinPoint){
logger.info("方法执行后...");
} @AfterReturning(returning="result", pointcut="log()")
public void doAfterReturnint(Object result){
logger.info("方法返回值:" + result);
}
}

回顾前一章的StudentController是这样的:

/**
* 添加学生
* @param student
* @return
*/
@RequestMapping("/add")
public String add(@Valid Student student, BindingResult bindingResult){
if(bindingResult.hasErrors()){
return bindingResult.getFieldError().getDefaultMessage();
}else{
studentService.add(student);
return "添加成功";
}
}

测试:

http://localhost/studentAdd.html正常添加一个学生,查看控制台信息:

2018-03-25 16:34:53.984  INFO 3744 --- [p-nio-80-exec-1] com.cy.aspect.RequestAspect              : 方法执行前...
2018-03-25 16:34:53.984 INFO 3744 --- [p-nio-80-exec-1] com.cy.aspect.RequestAspect : url: /student/add
2018-03-25 16:34:53.984 INFO 3744 --- [p-nio-80-exec-1] com.cy.aspect.RequestAspect : ip: 0:0:0:0:0:0:0:1
2018-03-25 16:34:53.984 INFO 3744 --- [p-nio-80-exec-1] com.cy.aspect.RequestAspect : method: POST
2018-03-25 16:34:53.986 INFO 3744 --- [p-nio-80-exec-1] com.cy.aspect.RequestAspect : class.method: com.cy.controller.StudentController.add
2018-03-25 16:34:53.986 INFO 3744 --- [p-nio-80-exec-1] com.cy.aspect.RequestAspect : args: [Ljava.lang.Object;@4232f676
2018-03-25 16:34:53.986 INFO 3744 --- [p-nio-80-exec-1] com.cy.aspect.RequestAspect : Student [id=null, name=余学海, age=28]
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: insert into t_student (age, name, id) values (?, ?, ?)
2018-03-25 16:34:54.067 INFO 3744 --- [p-nio-80-exec-1] com.cy.aspect.RequestAspect : 方法执行后...
2018-03-25 16:34:54.067 INFO 3744 --- [p-nio-80-exec-1] com.cy.aspect.RequestAspect : 方法返回值:添加成功

spring boot学习(8) SpringBoot 之切面AOP的更多相关文章

  1. spring boot 学习(五)SpringBoot+MyBatis(XML)+Druid

    SpringBoot+MyBatis(xml)+Druid 前言 springboot集成了springJDBC与JPA,但是没有集成mybatis,所以想要使用mybatis就要自己去集成. 主要是 ...

  2. spring boot学习(十三)SpringBoot缓存(EhCache 2.x 篇)

    SpringBoot 缓存(EhCache 2.x 篇) SpringBoot 缓存 在 Spring Boot中,通过@EnableCaching注解自动化配置合适的缓存管理器(CacheManag ...

  3. spring boot 学习(十)SpringBoot配置发送Email

    SpringBoot配置发送Email 引入依赖 在 pom.xml 文件中引入邮件配置: <dependency> <groupId>org.springframework. ...

  4. spring boot学习(4) SpringBoot 之Spring Data Jpa 支持(1)

    第一节:Spring Data Jpa 简介 Spring-Data-Jpa JPA(Java Persistence API)定义了一系列对象持久化的标准,目前实现这一规范的产品有Hibernate ...

  5. spring boot学习(2) SpringBoot 项目属性配置

    第一节:项目内置属性 application.properties配置整个项目的,相当于以前的web.xml: 注意到上一节的访问HelloWorld时,项目路径也没有加:直接是http://loca ...

  6. spring boot学习(3) SpringBoot 之MVC 支持

    第一节:@RequestMapping 配置url 映射   第二节:@Controller 处理http 请求 转发到一个页面,以前是转发到jsp页面,现在使用freemarker: 在pom.xm ...

  7. spring boot学习(7) SpringBoot 之表单验证

    第一节:SpringBoot 之表单验证@Valid 是spring-data-jpa的功能:   下面是添加学生的信息例子,要求姓名不能为空,年龄大于18岁.   贴下代码吧: Student实体: ...

  8. spring boot学习(6) SpringBoot 之事务管理

    两个操作要么同时成功,要么同时失败: 事务的一致性: 以前学ssh ssm都有事务管理service层通过applicationContext.xml配置,所有service方法都加上事务操作: 用来 ...

  9. Spring boot 学习八 Springboot的filter

    一:  传统的javaEE增加Filter是在web.xml中配置,如以下代码: <filter> <filter-name>TestFilter</filter-nam ...

随机推荐

  1. JavaScript 如何断平台

    isMobile = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgen ...

  2. try catch之ajax调错

  3. 行级锁 java||数据库

    http://www.cnblogs.com/xiyubaby/p/4623516.html select * from t for update 会等待行锁释放之后,返回查询结果. select * ...

  4. [原] Android上使用native IO

    首先, 官方google play对APK大小有限制: 50M.( https://support.google.com/googleplay/android-developer/answer/113 ...

  5. replicatedhq-ship 基于Kustomize 项目的快速kubernetes 应用部署工具

    replicatedhq-ship 是对Kustomize 项目的扩展,我们可以用它来快速的进行三方应用的管理部署, 可以和helm,kubernetes 清单文件,knative 集成,我们可以方便 ...

  6. The dis/advantage of forward declaration

    In our projects, in C++ head file, if reference to some classes (reference or pointer), instead of i ...

  7. Using C++ new() placement in embedded system

    For new(), there are three definition in C++11, which are listed below. throwing (1) void* operator ...

  8. 数学与猜想 合情推理模式 (G. 波利亚 著)

    第十二章 几个著名模式 (已看) $1. 证实一个结论 $2. 连续证实几个结论 $3. 证实一个未必可信的结论 $4. 类比推理 $5. 加深类比 $6. 被隐没的类比推理 第十三章 更多的模式与最 ...

  9. java_main

    Java中用户向系统传递参数的三种基本方式 main方法 在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的 ...

  10. c++内存泄漏原因及解决办法(智能指针)

    内存泄漏 由于疏忽或错误造成程序未能释放已经不再使用的内存的情况.内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费. 内存泄露的 ...