自我表扬:《Dubbo 实现原理与源码解析 —— 精品合集》
表扬自己:《D数据库实体设计合集》

摘要: 原创出处 https://muyinchen.github.io/2016/12/25/%E8%B0%88%20%60AOP%60%20%E7%9A%84%E9%80%9A%E4%BF%97%E7%90%86%E8%A7%A3/ 「一叶知秋」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

最近在翻译Spring Framework 5.0.0.M3中文文档 ,看到AOP时索性把自己的理解写写。
Spring的面向方面的编程(AOP),国内大都说面向切面,其实我还是觉得面向方面最恰当,何解?那就扯一扯。

1. AOP相关的概念

1) Aspect :切面,切入系统的一个切面。比如事务管理是一个切面,权限管理也是一个切面;

2) Join point :连接点,也就是可以进行横向切入的位置;

3) Advice :通知,切面在某个连接点执行的操作(分为: Before advice , After returning advice , After throwing advice , After (finally) advice , Around advice );

4) Pointcut :切点,符合切点表达式的连接点,也就是真正被切入的地方;

这就好比一团面,都是一团白面,根据食谱的不同,我们做什么样的面食即可,厨师关心的是做法,而客人关心的是色香味,再进一步的说,我同样的做面方法,完全可以用不一样的面粉(白面,玉米面,荞麦面等等),由此便可抽象出面团便是所谓的切点,而面团的加工,比如加水,放鸡蛋,放油,盐等的各种加工便是面的前置方法Before advice,将面团炸,煎,煮等做出成品来便是其后置方法After advice ,期间有所谓的环绕方法Around advice ,而客人的品评则是finally advice 中间出现问题了所造成的事件 After throwing advice 仅供理解,里面可能有不恰当的地方,但自己写代码的时注意即可,由此,这个做面的过程便是面向方面编程即所谓的一个切面(Aspect )

AOP的核心思想所在便是要求程序员专注于自己的逻辑业务,而非这团面,得以更好的去处理各种问题,从本质上进行解耦。

最后,再贴上一段代码来做参考对比:

@Aspect
@Component // for auto scan
//@Order(2)
public class LogInterceptor {
@Pointcut("execution(public * net.aazj.service..*.getUser(..))")
public void myMethod(){};
@Before("myMethod()")
public void before() {
System.out.println("method start");
}
@After("myMethod()")
public void after() {
System.out.println("method after");
}
@AfterReturning("execution(public * net.aazj.mapper..*.*(..))")
public void AfterReturning() {
System.out.println("method AfterReturning");
}
@AfterThrowing("execution(public * net.aazj.mapper..*.*(..))")
// @Around("execution(public * net.aazj.mapper..*.*(..))")
public void AfterThrowing() {
System.out.println("method AfterThrowing");
}
@Around("execution(public * net.aazj.mapper..*.*(..))")
public Object Around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("method Around");
SourceLocation sl = jp.getSourceLocation();
Object ret = jp.proceed();
System.out.println(jp.getTarget());
return ret;
}
@Before("execution(public * net.aazj.service..*.getUser(..)) && args(userId,..)")
public void before3(int userId) {
System.out.println("userId-----" + userId);
}
@Before("myMethod()")
public void before2(JoinPoint jp) {
Object[] args = jp.getArgs();
System.out.println("userId11111: " + (Integer)args[0]);
System.out.println(jp.getTarget());
System.out.println(jp.getThis());
System.out.println(jp.getSignature());
System.out.println("method start");
}
}

666. 彩蛋

如果你对 Spring 感兴趣,欢迎加入我的知识星球一起交流。

知识星球

文章目录
  1. 1. 666. 彩蛋