对于视频【https://www.bilibili.com/video/BV1yK411M7hb】,记录一下对部分代码产生的一些理解。
一、用Controller类定义网页和返回给网页的值
@RestController//①
public class HelloController {
@GetMapping("/hello1")//②
public String Hello2(@RequestParam("str") String name){
return "hello :"+name;
}
}
①@RestController可以把返回值传回网页,这个返回值来自于类中方法。
②@GetMapping是@RequestMapping的一种,用于为指定网页定义访问时执行的方法。 @GetMapping("/hello1")也可以用@RequestMapping(value = "/hello1", method = ReuqstMethod.GET)代替。值的作用是指定访问的网页,如@GetMapping("/hello1")指访问【localhost:8080/hello1&str=hsf】时将会把调用方法hello2并将参数str通过@RequestParam("str")传给String name,最终生成返回值"hello :hsf"。
当我们想要查看Hello2中参数是否接收到,或者想要写日志,如果不使用切面则一定要在目标方法Hello2中加入相应的代码(打印、logger等)。而使用切面来编写这些可重用的代码则不用修改Hello2。因为切面不是由目标方法动调动来被动运行的,而是在检测到目标方法运行时主动运行的。也就是说:
1、目标方法自顾自运行就好,无需加入调动切面的语句。
2、在定义切面的时候需要定义目标方法有哪些,以此来实现非入侵式的功能增加。
二、定义切面来观察参数
@Aspect
@Component
public class MyAdvice {
private Logger logger = LoggerFactory.getLogger(MyAdvice.class);
//定义切面
@Pointcut(value = "execution( * com.hsf.spring.aop.controller.*.*(..))")
public void MyPointcut(){
}
//定义通知
@Around("MyPointcut()")
public Object myLogger(ProceedingJoinPoint proceedingJoinPoint)
throws Throwable {
String className = proceedingJoinPoint.getTarget().getClass().toString();
String methodName = proceedingJoinPoint.getSignature().getName();
Object[] array = proceedingJoinPoint.getArgs();
ObjectMapper mapper = new ObjectMapper();
logger.info("调用前:" + className + " : "
+ methodName + "参数为:" + mapper.writeValueAsString(array));
//↑以上是myPointcut执行前↑
Object obj = proceedingJoinPoint.proceed();
//↓以下是myPointcut执行后↓
logger.info("调用后:" + className + " : "
+ methodName + "返回值为:" + mapper.writeValueAsString(obj));
return obj;
}
}
切面用于规定目标方法。
定义切点Pointcout:
定义切点并定义切点在哪些地方执行,采用@Pointcut注解完成。
如@Pointcut(public * XXX.*.*(..))
【切点定义规则:修饰符+返回类型+包下的类(第一个*)+类中的方法(第二个*)+方法参数】 修饰符可以不写但不能是*,'*'和'..'都代表不限制,但是'..'只能用于表名参数无限制。
@Pointcut是方法注解,加在方法上。加上注解后,方法就会变成切面,在注解中指定的包.类.方法运行时自动接收目标方法运行时的对象信息。
而通知则定义了运行切点时所执行的事务,这就是可重用代码部分。这部分代码可以在不同的时刻运行,而定义通知是否运行的是由@Around("MyPointcut()")所定义的切面来决定。
即切面先检测到目标方法的运行,然后切面来调动通知运行。