1.定义切面类Aspect
增添:
@Component 告诉Spring容器扫描这个组件
@Aspect 告知Spring这个类是个切面类
两个注解
/**
* 定义切面类
**/
@Aspect
@Component
public class LoggingAdvice{
private Logger logger = LoggerFactory.getLogger(LoggingAdvice.class);
}
2.定义切点Pointcut
定义切点,
并定义在哪些地方执行。
采用:@Pointcut注解
@Pointcut(public * com.xxx.xxx.*.*(..))
规则
修饰符(可不写,但不能用*)+ 返回值 + 包下的类 + 方法参数 (‘*’代表不限,‘..’两个点代表参数不限)
/**
* 切点名称myPointcut,返回类型不限;com.quanfon.sprint.aop.controller包下所有的类,所有方法,参数不限
**/
@Pointcut(value = "execution ( * com.quanfon.sprint.aop.controller.*.*(..))")
public void myPointcut(){
}
3.定义Advice通知
利用通知的5种注解
@Before
@After
@AfterReturning
@Around
来完成在某些切点的增强动作。
比如
@Before("myPointcut()")
myPointcut为第二步骤定义的切点
@Around("myPointcut()")
public Object applicationLogger(ProceedingJointPoint pjp) throws Throwable{
String methodName = pjp.getSignature().getName();
String className = pjp.getTarget().getClass().toString();
ObjectMapper m = new ObjectMapper();
Object[] array = pjp.getArgs();
logger.info("调用前:" + className + ":" + methodName + "args = " + m.writeValueAsString(array));
Object obj = proceedingJoinPoint.proceed();
logger.info("调用后:" + className + ":" methodName + "返回:" + m.writeValueAsString(obj));
return obj;
}
栗子
Controller
package com.sag.spring.aop.controller;
@RestController
public class hellocontroller {
@GetMapping("/hello")
public String hello(@RequestParam("name")String name){
return "hello" + name;
}
@GetMapping("/hello1")
public String hello1(@RequestParam("name")String name,@RequestParam("age")String age){
return "hello1:" + name + ",age=" + age;
}
}
package com.sag.spring.aop;
@Aspect
@Component
public class myAdvie {
private Logger logger = LoggerFactory.getLogger(myAdvie.class);
/**
* 定义切面
*/
@Pointcut(value = "execution ( * com.sag.spring.aop.controller.*.*(..))")
public void myPointcut(){
}
@Around("myPointcut()")
public Object myLogger(ProceedingJoinPoint pjp) throws Throwable {
String className = pjp.getTarget().getClass().toString();
String methodName = pjp.getSignature().getName();
Object[] array = pjp.getArgs();
ObjectMapper objectMapper = new ObjectMapper();
logger.info("调用之前。。。。。。。className:"+ className + ";methodName:" + methodName + ";传递参数:" + objectMapper.writeValueAsString(array));
//调用目标函数执行
Object proceed = pjp.proceed();
logger.info("调用后。。。。。。。className:"+ className + ";methodName:" + methodName + ";返回值:" + objectMapper.writeValueAsString(proceed));
return proceed;
}
}