在方法執行的前后,切入代碼;經典的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 : 方法返回值:添加成功