aop面向切面的编程Aspect Oriented Programming
我想创建一个类来监听controller ,当controller执行方法的时候将入参和输出参数打印出来
package com.wdg.controller;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class ServiceAspect {
private Logger logger = LoggerFactory.getLogger(ServiceAspect.class);
// 检测muyan controller 中所有的方法
private final String ExpGetResultDataPonit = "execution(* com.wdg.controller..*.*(..))";
@Pointcut(ExpGetResultDataPonit)
public void excuteService() {
}
// 执行方法前的拦截方法
@Before("excuteService()")
public void doBeforeMethod(JoinPoint joinPoint) {
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm:ss");
logger.info("-----" + sdf.format(new Date()) + "--执行方法" + joinPoint.getTarget().getClass().getName() + "-----");
try {
Object[] obj = joinPoint.getArgs();
logger.info("-----用户传入参数:{}", obj[0].toString() + "-----");
} catch (Exception e) {
logger.info("----无参数的方法-----");
}
}
/**
* 后置返回通知 这里需要注意的是: 如果参数中的第一个参数为JoinPoint,则第二个参数为返回值的信息
* 如果参数中的第一个参数不为JoinPoint,则第一个参数为returning中对应的参数 returning
* 限定了只有目标方法返回值与通知方法相应参数类型时才能执行后置返回通知,否则不执行,对于returning对应的通知方法参数为Object类型将匹配任何目标返回值
*/
@AfterReturning(value = "excuteService()", returning = "returnValue")
public void doAfterAdvice(JoinPoint joinPoint, Object returnValue) {
logger.info("-----执行方法" + joinPoint.getSignature().getName() + "返回值为{}-----", returnValue.toString());
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm:ss");
logger.info(
"-----" + sdf.format(new Date()) + "--结束调用方法" + joinPoint.getTarget().getClass().getName() + "-----");
}
/**
* 后置最终通知(目标方法只要执行完了就会执行后置通知方法)
*/
// @After("excuteService()")
public void doAfterAdvice(JoinPoint joinPoint) {
System.out.println("后置通知执行了!!!!");
}
/**
* 环绕通知: 环绕通知非常强大,可以决定目标方法是否执行,什么时候执行,执行时是否需要替换方法参数,执行完毕是否需要替换返回值。
* 环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型
*/
// @Around(ExpGetResultDataPonit)
public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
System.out.println("正在执行的方法的名称:" + proceedingJoinPoint.getSignature().getClass().getName());
processInputArg(proceedingJoinPoint.getArgs());
try {// obj之前可以写目标方法执行前的逻辑
Object obj = proceedingJoinPoint.proceed();// 调用执行目标方法
processOutPutObj(obj);
return obj;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return null;
}
/**
* 处理返回对象
*/
private void processOutPutObj(Object obj) {
System.out.println("OBJ 原本为:" + obj.toString());
}
/**
* 处理输入参数
*
* @param args 入参列表
*/
private void processInputArg(Object[] args) {
for (Object arg : args) {
System.out.println("ARG原来为:" + arg);
}
}
}
private final String ExpGetResultDataPonit = "execution(* com.wdg.controller..*.*(..))";
execution 里面是我们监听的类
@before
@after
分别是前执行方法和后执行方法
pom.xml需要引入的类:
<!-- http://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
<!-- http://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<!-- http://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.2</version>
</dependency>
最后,我们需要在springMVC-servlet.xml,引入:
<aop:aspectj-autoproxy proxy-target-class="true" />
在文件头部需要:
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
xmlns:aop="http://www.springframework.org/schema/aop"
上面 就可以实现我们的aop的功能了
上面仅仅是利用aop做一个简单的日志输出,
系统对你有所帮助