Spring Aop理解
官方解释
AOP(Aspect-Oriented Programming)指一种程序设计范型,该范型以一种称为切面(aspect)的语言构造为基础,切面是一种新的模块化机制,用来描述分散在对象、类或方法中的横切关注点(crosscutting concern)。
一句话概括就是Spirng核心思想:面向切面编程。
Spring Aop的简单使用
在简单使用Aop之前,我们首先构想一个案例,具体案例如下所示:
假如我们在访问某些请求之前,需要针对某些请求进行相应的操作,那么应该有哪些解决办法?
1、在所需要处理的每一个请求中,添加我们的处理规则!
2、定义一个拦截器,进行拦截我们的请求,进行相应的处理!
3、使用Aop思想,定义一个自定义注解进行切入处理!
以上就是我针对需求,提出的三种解决办法,简单的介绍一下其中的利弊!
第一种方法:会造成大量的重复代码,不符合我们简化代码的思想!
第二种方法:需要在拦截器中维护我们的请求名单,也是符合我们需求,但是不是最好的解决办法!
第三种方法:通过使用Aop思想处理,即用即拿,是当下我认为的最好的解决思路之一!
自定义注解
简单认识自定义的注解
定义一个注解操作:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE,ElementType.METHOD})
public @interface MyAop {
@AliasFor("value")
String name() default "";
@AliasFor("name")
String value() default "";
}
以上就是我们自己定义了一个注解操作!
注解解释
@Retention注解:
当前注解的生效时间,具体有三个类型:SOURCE、CLASS、RUNTIME
@Retention注解:
当前注解的作用位置,通俗的解释,就是当前注解可以放在哪些位置上。
自定义注解结合切点思想
@Aspect注解定义在类上,证明当前类是使用Aop切面的注解操作类!
具体代码如下所示:
@Aspect
@Component
public class Aspct {
private static final Logger LOG = LoggerFactory.getLogger(Aspct.class);
/**
* 匹配相应的注解:@MyAop,也即是定义一个切入点
*/
@Pointcut(value = "@annotation(com.aop.openfeign.aop.MyAop)")
public void method() {
}
/**
* 当方法上由此注解,切入进当前方法中
* 环绕
* @param point
* @return
*/
@Around(value = "method()")
public Object doMethod(ProceedingJoinPoint point) {
LOG.info("环绕通知开始(@Around)。。。。。");
// 执行方法,可无参/带参,也就是执行此方法之前触发前置、后置通知(获取的是值)
Object proceed = point.proceed();
LOG.info("环绕通知结束(@Around)。。。。。");
return proceed;
}
/**
* 后置通知
* @param point
*/
@Before(value = "method()")
public void beforeMethod(JoinPoint joinPoint){
LOG.info("前置通知开始(@Before)。。。。。");
LOG.info("前置通知结束(@Before)。。。。。");
}
/**
* 后置通知
* @param point
*/
@After(value = "method()")
public void afterMethod(JoinPoint point){
LOG.info("后置通知开始(@After)。。。。。");
LOG.info(point.getKind());
LOG.info("后置通知结束(@After)。。。。。");
}
/**
* 后置通知:连接点正常执行完毕后的通知
* @param joinPoint
* 指定切点
* @param obj
* 定的是返回值:也就是接口查询的返回值,环绕的返回值
*/
@AfterReturning(value = "method()",returning = "obj")
public void afterReturning(JoinPoint joinPoint,Object obj){
LOG.info("后置通知正常返回-->"+obj);
}
/**
* 异常通知:也就是前置执行完成后,若有异常执行
* @param joinPoint
* @param ex
*/
@AfterThrowing(value = "method()", throwing = "ex")
public void afterThrowing(JoinPoint joinPoint,Exception ex){
LOG.info("异常通知-->"+ex.getMessage());
}
}
相关参数的说明:
环绕通知:
// 获取注解的参数
MethodSignature ms = (MethodSignature) point.getSignature();
Method method = ms.getMethod();
MyAop annotation = method.getAnnotation(MyAop.class);
String key = annotation.name();
String value = annotation.value();
前置通知:
Object[] getArgs():返回此连接点处(目标方法)的参数,目标方法无参数时,返回空数组
Signature getSignature():返回连接点处的签名。
Object getTarget():返回目标对象
Object getThis():返回当前正在执行的对象
StaticPart getStaticPart():返回一个封装此连接点的静态部分的对象。
SourceLocation getSourceLocation():返回与连接点对应的源位置
String toLongString():返回连接点的扩展字符串表示形式。
String toShortString():返回连接点的缩写字符串表示形式。
String getKind():返回表示连接点类型的字符串
Aop测试
访问接口:
http://localhost:8089/aop/getAOP/1
正常执行流程:
异常执行流程:
若不执行point.proceed();方法,流程如下:
以上就是结合Aop思想,进行切面编程,若有不足之处,请指正!