Spring AOP简介
AOP把业务功能分为核心、非核心两部分。
- 核心业务功能:用户登录、增加数据、删除数据。
- 非核心业务功能:性能统计、日志、事务管理。
在Spring的面向切面编程(AOP)思想里,非核心业务功能被定义为切面。核心业务功能和切面功能先被分别进行独立开发,然后把切面功能和核心业务功能“编织”在一起,这就是AOP。 - 切入点(pointcut):在哪些类、哪些方法上切入。
- 通知(advice):在方法钱、方法后、方法前后做什么。
- 切面(aspect):切面=切入点+通知。即在什么时机、什么地方、做什么。
- 织入(weaving):把切面加入对象,并创建出代理对象的过程。
- 环绕通知:AOP中最强大、灵活的通知,它集成了前置和后置通知,保留了连接点原有的方法。
实例演示
- 定义切点
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)
- 修饰符匹配(modifier-pattern?)
- 返回值匹配(ret-type-pattern)可以为*表示任何返回值,全路径的类名等
- 类路径匹配(declaring-type-pattern?)
- 方法名匹配(name-pattern)可以指定方法名 或者 代表所有, set 代表以set开头的所有方法
- 参数匹配((param-pattern))可以指定具体的参数类型,多个参数间用“,”隔开,各个参数也可以用“”来表示匹配任意类型的参数,如(String)表示匹配一个String参数的方法;(,String) 表示匹配有两个参数的方法,第一个参数可以是任意类型,而第二个参数是String类型;可以用(…)表示零个或多个任意参数
- 异常类型匹配(throws-pattern?)
- 其中后面跟着“?”的是可选项
@Pointcut("execution(public * com.gd..*.*(..))")
public void aopWebLog() {
}
@Before("aopWebLog()")
public void doBefore(JoinPoint joinPoint) throws Throwable{
startTime.set(System.currentTimeMillis());
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 记录下请求内容
log.info("URL:" + request.getRequestURL().toString());
log.info("HTTP方法:" + request.getMethod());
log.info("IP:" + request.getRemoteAddr());
log.info("类的方法:" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
log.info("参数:" + request.getQueryString());
}
@AfterReturning(pointcut = "aopWebLog()", returning = "retObject")
public void doAfterReturning(Object retObject) throws Throwable{
// 处理完请求,返回内容
log.info("应答值:" + retObject);
log.info("费时:" + (System.currentTimeMillis() - startTime.get()) + "ms");
}
@AfterThrowing(pointcut = "aopWebLog()", throwing = "ex")
public void addAfterThrowingLogger(JoinPoint joinPoint, Exception ex) {
log.error("执行异常,{}", ex);
}
代码解释:
- @Before:在切入点开始处切入内容。
- @After:在切入点结尾处切入内容。
- @AfterReturning:在切入点返回(return)内容之后切入内容,可以用来对处理返回值做一些加工处理。
- @Around:在切入点前后切入内容,并控制何时执行切入点自身的内容。
- @AfterThrowing:用来处理当切入内容部分抛出异常之后的处理逻辑。
- @Aspect:标记为切面类。
- @Component:把切面类加入IoC容器中,让Spring进行管理。