什么是AOP?
AOP即面向切面编程,可以说是面向对象编程OOP的一个补充和完善。OOP允许我们纵向定义纵向的关系(类-属性-方法),不适合定义横向关系。例如日志,权限等功能,这些功能横向分布在很多对象之中,这种横向散布的通用代码导致了大量代码重复,不利于复用。
AOP采用“横切”技术,剖开对象内部,把那些通用的代码封装成一个可重用模块,称为切面。简单说就是把那些与业务无关,却被业务模块所共同调用的逻辑封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。
AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。
AOP名词解释
- 横切关注点
对哪些方法进行拦截?拦截后做些什么?这是我们的横切关注点。 - 切面
通常是一个类,里面可以定义切入点和通知,即把横切关注点抽象为一个类。 - 连接点
能被拦截插入切面的点,指方法调用,方法返回,抛出异常。 - 切入点
在什么地方插入切面,使用明确的类或方法指定这些地方。 - 通知
通知就是切面要做的事,如记录日志等操作。 - 织入
将切面应用到目标对象并导致代理对象创建的过程 - 引入
在不修改代码的前提下,在运行期为类动态地添加一些方法或字段
如何使用AOP?
可以通过xml配置文件的形式,通过对切面,连接点,切入点,通知进行定义来使用AOP。也可以通过注解。下面讲解常用的注解方式:
第一步,引入相应的jar包或依赖
第二步,在配置文件中加入以下标签(Springboot项目省略这一步)
<context:component-scan base-package=“com.ctc” />//IOC自动扫包
<aop:aspectj-autoproxy />//使用AOP注解
第三步,通过@Component和@Aspect注解定义切面
第四步,通过@PointCut(“”)定义切入点
第五步,使用@Before@After@Around等注解定义连接点和通知
代码如下:
package com.example.demo;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class LogAspect {
public static Logger logger = LoggerFactory.getLogger(LogAspect.class);
@Pointcut("execution(public * com.example.demo.controller..*.*(..))")
public void allController(){
}
@Around("allController()")
public Object aroundController(ProceedingJoinPoint proceedingJoinPoint){
Object ret=null;
logger.info("AroundController running");
try {
ret = proceedingJoinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
logger.info("AroundController finish");
return ret;
}
}
当访问localhost:8080/register时控制台输出:
2020-04-02 20:39:54.793 INFO 6432 --- [nio-8080-exec-1] com.example.demo.LogAspect : AroundController running
2020-04-02 20:39:54.913 INFO 6432 --- [nio-8080-exec-1] com.example.demo.LogAspect : AroundController finish