-
前置通知(@Before):执行目标方法前拦截到的方法。只需要一个连接点,JoinPoint,即可获取拦截目标方法以及请求参数。
后置通知(@After):执行目标方法后拦截到的方法,不管方法是否抛出异常,都会走这个方法。只需要一个连接点,JoinPoint,即可获取当 前结束的方法名称。
返回通知(@AfterReturning):在方法正常执行通过之后执行的通知叫做返回通知。此时注意,不仅仅使用JoinPoint获取连接点信息,同时要在返回通知注解里写入,resut="result"。在切面方法参数中加入Object result,用于接受返回通知的返回结果。如果目标方法方法是void返回类型则返回NULL
异常通知(@AfterThrowing): 在执行目标方法过程中,如果方法抛出异常则会走此方法。和返回通知很相似,在注解中加入,throwing="ex",在切面方法中加入Exection ex用于接受异常信息
环绕通知(@Around):环绕通知需要携带ProceedingJoinPoint 这个类型的参数,环绕通知类似于动态代理的全过程ProceedingJoinPoint类型的参数可以决定是否执行目标函数环绕通知必须有返回值。其实就是包含了所有通知的全过程
查看全部 -
测试controller @RunWith(SpringRunner.class) @SpringBootTest @AutoConfigureMockMvc public class GrilController { @Autowired private MockMvc mvc; @Test public void girlList() throws Exception { mvc.perform( MockMvcRequestBuilders.get("/girl/girls")) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.content().string("abc")); } }查看全部
-
@Pointcut 注解中填写的内容与 @Before @After 两注解是一样的 为了避免代码重复书写,定义一个公用方法,@Pointcut注解声明切入点 @Before @After 两注解直接复用该方法切入点查看全部
-
1.AOP是什么?
AOP是一种范式,一种程序设计思想,不是一门语言,不止在Java中有;AOP是面向切面编程思想,即:针对垂直的业务逻辑处理过程,把问题水平切割为某个步骤或阶段;就是从不同的角度看问题,换个姿势看世界,不同的设计思想还有:
面向对象编程(OOP),如Java
面向过程编程(POP),如C
2.如何创建通知?
1)pom.xml中引入切面spring-boot-starter-aop
2)新建一个切面(@Aspect和@Component标志的类),然后在切面中创建通知,如使用@Before("execution(public List com.imooc.controller.GirlController.grilList(..))")标注某一个方式,使之成为public List com.imooc.controller.GirlController.grilList(..)方法的前置通知;当然,也可以使用*泛指某类下的所有方法:public * com.imooc.controller.GirlController.*(..),在返回类型位置的*代表返回任意类型都匹配,参数列表中的..代表匹配任意参数
查看全部 -
获取请求相关参数:
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest();
查看全部 -
1:@Valid表单验证
2:AOP拦截
3:异常统一处理
3.1:不用if来进行逻辑判断控制,直接抛异常
3.2:异常的抛出,需要有个code,还有msg两个参数,所以自己定义异常,继承runtimeException,不要继承Exception,不然不支持回滚
3.3:要抛出的异常太多的话,直接在异常里写code,和msg参数,太繁琐,写一个enum枚举来用。
4:单元测试
查看全部 -
为什么要统一异常处理,目的是为了所抛的异常格式变得的规范和更好处理,通常都是是json格式。
统一异常处理的步骤
建立一个Result类 :http请求返回的最外层对象,包括code msg data
写一个工具类:优化代码(减少重复代码)
查看全部 -
package com.imooc.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* Aspect切面类
* 主要是在切面类相互之前写Logger
*
* @Author:Liyoh-Frank Create by IntelliJ IDEA
* @Date: 2018/7/6 16:46
* @LoveAndThanks: Misty
*/
@Aspect
@Component
public class HttpAspect {
private final static Logger LOGGER = LoggerFactory.getLogger(HttpAspect.class);
//定义一个log,定义个切点--这样在下面就不用写一堆SB代码了
@Pointcut("execution(public * com.imooc.controller.GirlController.*(..))")
public void log() {
}
/**
* JoinPoint对象封装了SpringAop中切面方法的信息,
* 在切面方法中添加JoinPoint参数,就可以获取到封装了该方法信息的JoinPoint对象.
*
* @param joinPoint
*/
//Before记录Http请求
@Before("log()")
public void doBefore(JoinPoint joinPoint) {//JoinPoint可以获取方法名和方法参数
LOGGER.info("Before()");
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//url-请求的路径
LOGGER.info("url={}", request.getRequestURL());
//method 请求的方式
LOGGER.info("method={}", request.getMethod());
//ip 客户端的ip
LOGGER.info("ip={}", request.getRemoteAddr());
//请求的哪一个类的方法
LOGGER.info("class_method={}", joinPoint.getSignature().getDeclaringType() +
"." + joinPoint.getSignature().getName());
//类方法的参数
LOGGER.info("args={}", joinPoint.getArgs());
}
@After("log()")
public void doAfter() {
LOGGER.info("After()");
}
@AfterReturning(pointcut = "log()", returning = "object")
public void doAfterReturning(Object object) {
LOGGER.info("response={}", object);
}
}查看全部 -
举例挺好的,确实挺文艺
查看全部 -
已学习完,统一异常处理,AOP ,单元测试讲的不错,值得多次学习查看全部
-
在领域模型girl中声明如下:
@Min(value = 18, message = "未成年少女禁止入门")
在控制器的验证方法中加入:
@PostMapping(value = "/girls") public Result girlAdd(@Valid Girl girl, BindingResult bindingResult) { if (bindingResult.hasErrors()) { return ResultUtil.error(1, bindingResult.getFieldError().getDefaultMessage()); } girl.setCupSize(girl.getCupSize()); girl.setAge(girl.getAge()); return ResultUtil.success(girlRepository.save(girl)); }
@valid用于验证参数的正确性,BindingResult对象用来显示错误信息!
查看全部 -
AOP面向切面编程给我一个简单明了的例子就是:web应用中所有的URI请求都要经过安全验证,这是所有对象都有的共同性,显然,这么对象之间没有必要构造的继承关系,因为那样不太合适。面向切面的核心体现在对URI所对应的资源进行响应前,构造一个切入点,所有URI请求都要经过切入点的过滤和处理。大概这就是AOP
查看全部 -
@Before("log()") public void doBefore(JoinPoint joinPoint) { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = (HttpServletRequest) attributes.getRequest(); logger.info("url={}", request.getRequestURL()); logger.info("method={}", request.getMethod()); logger.info("ip={}", request.getRemoteAddr()); logger.info("class_method={}", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); logger.info("args ={}", joinPoint.getArgs()); logger.info("111111111111111111111111111111"); } @AfterReturning(returning = "object", pointcut = "log()") public void doAfterReturn(Object object) { logger.info("response={}", object); }查看全部
-
定义枚举类型查看全部
-
项目源码,https://github.com/Daoshun/girl,连接oracle版,需要的同学可以参考下。
查看全部
举报